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, 2001 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 do_builtin_setjmp_setup
56 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
57 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
58 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
59 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
60 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
62 ;; Attribute for cpu type.
63 ;; These must match the values for enum processor_type in sparc.h.
64 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc"
65 (const (symbol_ref "sparc_cpu_attr")))
67 ;; Attribute for the instruction set.
68 ;; At present we only need to distinguish v9/!v9, but for clarity we
69 ;; test TARGET_V8 too.
70 (define_attr "isa" "v6,v8,v9,sparclet"
72 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
73 (symbol_ref "TARGET_V8") (const_string "v8")
74 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
75 (const_string "v6"))))
78 (define_attr "arch" "arch32bit,arch64bit"
80 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
81 (const_string "arch32bit"))))
83 ;; Insn type. Used to default other attribute values.
85 ;; type "unary" insns have one input operand (1) and one output operand (0)
86 ;; type "binary" insns have two input operands (1,2) and one output (0)
87 ;; type "compare" insns have one or two input operands (0,1) and no output
88 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
91 "move,unary,binary,compare,load,sload,store,ialu,shift,uncond_branch,branch,call,sibcall,call_no_delay_slot,return,address,imul,fpload,fpstore,fp,fpmove,fpcmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc"
92 (const_string "binary"))
94 ;; Set true if insn uses call-clobbered intermediate register.
95 (define_attr "use_clobbered" "false,true"
96 (if_then_else (and (eq_attr "type" "address")
97 (match_operand 0 "clobbered_register" ""))
99 (const_string "false")))
101 ;; Length (in # of insns).
102 (define_attr "length" ""
103 (cond [(eq_attr "type" "load,sload,fpload")
104 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
105 (const_int 2) (const_int 1))
107 (eq_attr "type" "store,fpstore")
108 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
109 (const_int 2) (const_int 1))
111 (eq_attr "type" "address") (const_int 2)
113 (eq_attr "type" "binary")
114 (if_then_else (ior (match_operand 2 "arith_operand" "")
115 (match_operand 2 "arith_double_operand" ""))
116 (const_int 1) (const_int 3))
118 (eq_attr "type" "multi") (const_int 2)
120 (eq_attr "type" "move,unary")
121 (if_then_else (ior (match_operand 1 "arith_operand" "")
122 (match_operand 1 "arith_double_operand" ""))
123 (const_int 1) (const_int 2))]
127 (define_asm_attributes
128 [(set_attr "length" "1")
129 (set_attr "type" "multi")])
131 ;; Attributes for instruction and branch scheduling
133 (define_attr "in_call_delay" "false,true"
134 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
135 (const_string "false")
136 (eq_attr "type" "load,fpload,store,fpstore")
137 (if_then_else (eq_attr "length" "1")
138 (const_string "true")
139 (const_string "false"))
140 (eq_attr "type" "address")
141 (if_then_else (eq_attr "use_clobbered" "false")
142 (const_string "true")
143 (const_string "false"))]
144 (if_then_else (eq_attr "length" "1")
145 (const_string "true")
146 (const_string "false"))))
148 (define_delay (eq_attr "type" "call")
149 [(eq_attr "in_call_delay" "true") (nil) (nil)])
151 (define_attr "eligible_for_sibcall_delay" "false,true"
152 (symbol_ref "eligible_for_sibcall_delay (insn)"))
154 (define_delay (eq_attr "type" "sibcall")
155 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
157 (define_attr "leaf_function" "false,true"
158 (const (symbol_ref "current_function_uses_only_leaf_regs")))
160 (define_attr "eligible_for_return_delay" "false,true"
161 (symbol_ref "eligible_for_return_delay (insn)"))
163 (define_attr "in_return_delay" "false,true"
164 (if_then_else (and (and (and (eq_attr "type" "move,load,sload,store,binary,ialu")
165 (eq_attr "length" "1"))
166 (eq_attr "leaf_function" "false"))
167 (eq_attr "eligible_for_return_delay" "false"))
168 (const_string "true")
169 (const_string "false")))
171 (define_delay (and (eq_attr "type" "return")
172 (eq_attr "isa" "v9"))
173 [(eq_attr "in_return_delay" "true") (nil) (nil)])
175 ;; ??? Should implement the notion of predelay slots for floating point
176 ;; branches. This would allow us to remove the nop always inserted before
177 ;; a floating point branch.
179 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
180 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
181 ;; This is because doing so will add several pipeline stalls to the path
182 ;; that the load/store did not come from. Unfortunately, there is no way
183 ;; to prevent fill_eager_delay_slots from using load/store without completely
184 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
185 ;; because it prevents us from moving back the final store of inner loops.
187 (define_attr "in_branch_delay" "false,true"
188 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
189 (eq_attr "length" "1"))
190 (const_string "true")
191 (const_string "false")))
193 (define_attr "in_uncond_branch_delay" "false,true"
194 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
195 (eq_attr "length" "1"))
196 (const_string "true")
197 (const_string "false")))
199 (define_attr "in_annul_branch_delay" "false,true"
200 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
201 (eq_attr "length" "1"))
202 (const_string "true")
203 (const_string "false")))
205 (define_delay (eq_attr "type" "branch")
206 [(eq_attr "in_branch_delay" "true")
207 (nil) (eq_attr "in_annul_branch_delay" "true")])
209 (define_delay (eq_attr "type" "uncond_branch")
210 [(eq_attr "in_uncond_branch_delay" "true")
213 ;; Function units of the SPARC
215 ;; (define_function_unit {name} {num-units} {n-users} {test}
216 ;; {ready-delay} {issue-delay} [{conflict-list}])
219 ;; (Noted only for documentation; units that take one cycle do not need to
222 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
225 ;; (define_function_unit "alu" 1 0
226 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
228 ;; ---- cypress CY7C602 scheduling:
229 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
231 (define_function_unit "memory" 1 0
232 (and (eq_attr "cpu" "cypress")
233 (eq_attr "type" "load,sload,fpload"))
236 ;; SPARC has two floating-point units: the FP ALU,
237 ;; and the FP MUL/DIV/SQRT unit.
238 ;; Instruction timings on the CY7C602 are as follows
252 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
253 ;; More insns cause the chip to stall.
255 (define_function_unit "fp_alu" 1 0
256 (and (eq_attr "cpu" "cypress")
257 (eq_attr "type" "fp,fpmove"))
260 (define_function_unit "fp_mds" 1 0
261 (and (eq_attr "cpu" "cypress")
262 (eq_attr "type" "fpmul"))
265 (define_function_unit "fp_mds" 1 0
266 (and (eq_attr "cpu" "cypress")
267 (eq_attr "type" "fpdivs,fpdivd"))
270 (define_function_unit "fp_mds" 1 0
271 (and (eq_attr "cpu" "cypress")
272 (eq_attr "type" "fpsqrts,fpsqrtd"))
275 ;; ----- The TMS390Z55 scheduling
276 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
277 ;; one ld/st, one fp.
278 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
280 (define_function_unit "memory" 1 0
281 (and (eq_attr "cpu" "supersparc")
282 (eq_attr "type" "load,sload"))
285 (define_function_unit "memory" 1 0
286 (and (eq_attr "cpu" "supersparc")
287 (eq_attr "type" "fpload"))
290 (define_function_unit "memory" 1 0
291 (and (eq_attr "cpu" "supersparc")
292 (eq_attr "type" "store,fpstore"))
295 (define_function_unit "shift" 1 0
296 (and (eq_attr "cpu" "supersparc")
297 (eq_attr "type" "shift"))
300 ;; There are only two write ports to the integer register file
301 ;; A store also uses a write port
303 (define_function_unit "iwport" 2 0
304 (and (eq_attr "cpu" "supersparc")
305 (eq_attr "type" "load,sload,store,shift,ialu"))
308 ;; Timings; throughput/latency
309 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
317 (define_function_unit "fp_alu" 1 0
318 (and (eq_attr "cpu" "supersparc")
319 (eq_attr "type" "fp,fpmove,fpcmp"))
322 (define_function_unit "fp_mds" 1 0
323 (and (eq_attr "cpu" "supersparc")
324 (eq_attr "type" "fpmul"))
327 (define_function_unit "fp_mds" 1 0
328 (and (eq_attr "cpu" "supersparc")
329 (eq_attr "type" "fpdivs"))
332 (define_function_unit "fp_mds" 1 0
333 (and (eq_attr "cpu" "supersparc")
334 (eq_attr "type" "fpdivd"))
337 (define_function_unit "fp_mds" 1 0
338 (and (eq_attr "cpu" "supersparc")
339 (eq_attr "type" "fpsqrts,fpsqrtd"))
342 (define_function_unit "fp_mds" 1 0
343 (and (eq_attr "cpu" "supersparc")
344 (eq_attr "type" "imul"))
347 ;; ----- hypersparc/sparclite86x scheduling
348 ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
349 ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
350 ;; II/FF case is only when loading a 32 bit hi/lo constant
351 ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
352 ;; Memory delivers its result in one cycle to IU
354 (define_function_unit "memory" 1 0
355 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
356 (eq_attr "type" "load,sload,fpload"))
359 (define_function_unit "memory" 1 0
360 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
361 (eq_attr "type" "store,fpstore"))
364 (define_function_unit "sparclite86x_branch" 1 0
365 (and (eq_attr "cpu" "sparclite86x")
366 (eq_attr "type" "branch"))
369 ;; integer multiply insns
370 (define_function_unit "sparclite86x_shift" 1 0
371 (and (eq_attr "cpu" "sparclite86x")
372 (eq_attr "type" "shift"))
375 (define_function_unit "fp_alu" 1 0
376 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
377 (eq_attr "type" "fp,fpmove,fpcmp"))
380 (define_function_unit "fp_mds" 1 0
381 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
382 (eq_attr "type" "fpmul"))
385 (define_function_unit "fp_mds" 1 0
386 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
387 (eq_attr "type" "fpdivs"))
390 (define_function_unit "fp_mds" 1 0
391 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
392 (eq_attr "type" "fpdivd"))
395 (define_function_unit "fp_mds" 1 0
396 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
397 (eq_attr "type" "fpsqrts,fpsqrtd"))
400 (define_function_unit "fp_mds" 1 0
401 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
402 (eq_attr "type" "imul"))
405 ;; ----- sparclet tsc701 scheduling
406 ;; The tsc701 issues 1 insn per cycle.
407 ;; Results may be written back out of order.
409 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
411 (define_function_unit "tsc701_load" 4 1
412 (and (eq_attr "cpu" "tsc701")
413 (eq_attr "type" "load,sload"))
416 ;; Stores take 2(?) extra cycles to complete.
417 ;; It is desirable to not have any memory operation in the following 2 cycles.
418 ;; (??? or 2 memory ops in the case of std).
420 (define_function_unit "tsc701_store" 1 0
421 (and (eq_attr "cpu" "tsc701")
422 (eq_attr "type" "store"))
424 [(eq_attr "type" "load,sload,store")])
426 ;; The multiply unit has a latency of 5.
427 (define_function_unit "tsc701_mul" 1 0
428 (and (eq_attr "cpu" "tsc701")
429 (eq_attr "type" "imul"))
432 ;; ----- The UltraSPARC-1 scheduling
433 ;; UltraSPARC has two integer units. Shift instructions can only execute
434 ;; on IE0. Condition code setting instructions, call, and jmpl (including
435 ;; the ret and retl pseudo-instructions) can only execute on IE1.
436 ;; Branch on register uses IE1, but branch on condition code does not.
437 ;; Conditional moves take 2 cycles. No other instruction can issue in the
438 ;; same cycle as a conditional move.
439 ;; Multiply and divide take many cycles during which no other instructions
441 ;; Memory delivers its result in two cycles (except for signed loads,
442 ;; which take one cycle more). One memory instruction can be issued per
445 (define_function_unit "memory" 1 0
446 (and (eq_attr "cpu" "ultrasparc")
447 (eq_attr "type" "load,fpload"))
450 (define_function_unit "memory" 1 0
451 (and (eq_attr "cpu" "ultrasparc")
452 (eq_attr "type" "sload"))
455 (define_function_unit "memory" 1 0
456 (and (eq_attr "cpu" "ultrasparc")
457 (eq_attr "type" "store,fpstore"))
460 (define_function_unit "ieuN" 2 0
461 (and (eq_attr "cpu" "ultrasparc")
462 (eq_attr "type" "ialu,binary,move,unary,shift,compare,call,sibcall,call_no_delay_slot,uncond_branch"))
465 (define_function_unit "ieu0" 1 0
466 (and (eq_attr "cpu" "ultrasparc")
467 (eq_attr "type" "shift"))
470 (define_function_unit "ieu0" 1 0
471 (and (eq_attr "cpu" "ultrasparc")
472 (eq_attr "type" "cmove"))
475 (define_function_unit "ieu1" 1 0
476 (and (eq_attr "cpu" "ultrasparc")
477 (eq_attr "type" "compare,call,sibcall,call_no_delay_slot,uncond_branch"))
480 (define_function_unit "cti" 1 0
481 (and (eq_attr "cpu" "ultrasparc")
482 (eq_attr "type" "branch"))
485 ;; Timings; throughput/latency
486 ;; FMOV 1/1 fmov, fabs, fneg
488 ;; FADD 1/3 add/sub, format conv, compar
494 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
496 ;; FDIV{s,d}/FSQRT{s,d} are given their own unit since they only
497 ;; use the FPM multiplier for final rounding 3 cycles before the
498 ;; end of their latency and we have no real way to model that.
500 ;; ??? This is really bogus because the timings really depend upon
501 ;; who uses the result. We should record who the user is with
502 ;; more descriptive 'type' attribute names and account for these
503 ;; issues in ultrasparc_adjust_cost.
505 (define_function_unit "fadd" 1 0
506 (and (eq_attr "cpu" "ultrasparc")
507 (eq_attr "type" "fpmove"))
510 (define_function_unit "fadd" 1 0
511 (and (eq_attr "cpu" "ultrasparc")
512 (eq_attr "type" "fpcmove"))
515 (define_function_unit "fadd" 1 0
516 (and (eq_attr "cpu" "ultrasparc")
517 (eq_attr "type" "fp"))
520 (define_function_unit "fadd" 1 0
521 (and (eq_attr "cpu" "ultrasparc")
522 (eq_attr "type" "fpcmp"))
525 (define_function_unit "fmul" 1 0
526 (and (eq_attr "cpu" "ultrasparc")
527 (eq_attr "type" "fpmul"))
530 (define_function_unit "fadd" 1 0
531 (and (eq_attr "cpu" "ultrasparc")
532 (eq_attr "type" "fpcmove"))
535 (define_function_unit "fdiv" 1 0
536 (and (eq_attr "cpu" "ultrasparc")
537 (eq_attr "type" "fpdivs"))
540 (define_function_unit "fdiv" 1 0
541 (and (eq_attr "cpu" "ultrasparc")
542 (eq_attr "type" "fpdivd"))
545 (define_function_unit "fdiv" 1 0
546 (and (eq_attr "cpu" "ultrasparc")
547 (eq_attr "type" "fpsqrts"))
550 (define_function_unit "fdiv" 1 0
551 (and (eq_attr "cpu" "ultrasparc")
552 (eq_attr "type" "fpsqrtd"))
555 ;; Compare instructions.
556 ;; This controls RTL generation and register allocation.
558 ;; We generate RTL for comparisons and branches by having the cmpxx
559 ;; patterns store away the operands. Then, the scc and bcc patterns
560 ;; emit RTL for both the compare and the branch.
562 ;; We do this because we want to generate different code for an sne and
563 ;; seq insn. In those cases, if the second operand of the compare is not
564 ;; const0_rtx, we want to compute the xor of the two operands and test
567 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
568 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
569 ;; insns that actually require more than one machine instruction.
571 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
573 (define_expand "cmpsi"
575 (compare:CC (match_operand:SI 0 "register_operand" "")
576 (match_operand:SI 1 "arith_operand" "")))]
580 sparc_compare_op0 = operands[0];
581 sparc_compare_op1 = operands[1];
585 (define_expand "cmpdi"
587 (compare:CCX (match_operand:DI 0 "register_operand" "")
588 (match_operand:DI 1 "arith_double_operand" "")))]
592 sparc_compare_op0 = operands[0];
593 sparc_compare_op1 = operands[1];
597 (define_expand "cmpsf"
598 ;; The 96 here isn't ever used by anyone.
600 (compare:CCFP (match_operand:SF 0 "register_operand" "")
601 (match_operand:SF 1 "register_operand" "")))]
605 sparc_compare_op0 = operands[0];
606 sparc_compare_op1 = operands[1];
610 (define_expand "cmpdf"
611 ;; The 96 here isn't ever used by anyone.
613 (compare:CCFP (match_operand:DF 0 "register_operand" "")
614 (match_operand:DF 1 "register_operand" "")))]
618 sparc_compare_op0 = operands[0];
619 sparc_compare_op1 = operands[1];
623 (define_expand "cmptf"
624 ;; The 96 here isn't ever used by anyone.
626 (compare:CCFP (match_operand:TF 0 "register_operand" "")
627 (match_operand:TF 1 "register_operand" "")))]
631 sparc_compare_op0 = operands[0];
632 sparc_compare_op1 = operands[1];
636 ;; Now the compare DEFINE_INSNs.
638 (define_insn "*cmpsi_insn"
640 (compare:CC (match_operand:SI 0 "register_operand" "r")
641 (match_operand:SI 1 "arith_operand" "rI")))]
644 [(set_attr "type" "compare")])
646 (define_insn "*cmpdi_sp64"
648 (compare:CCX (match_operand:DI 0 "register_operand" "r")
649 (match_operand:DI 1 "arith_double_operand" "rHI")))]
652 [(set_attr "type" "compare")])
654 (define_insn "*cmpsf_fpe"
655 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
656 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
657 (match_operand:SF 2 "register_operand" "f")))]
662 return \"fcmpes\\t%0, %1, %2\";
663 return \"fcmpes\\t%1, %2\";
665 [(set_attr "type" "fpcmp")])
667 (define_insn "*cmpdf_fpe"
668 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
669 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
670 (match_operand:DF 2 "register_operand" "e")))]
675 return \"fcmped\\t%0, %1, %2\";
676 return \"fcmped\\t%1, %2\";
678 [(set_attr "type" "fpcmp")])
680 (define_insn "*cmptf_fpe"
681 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
682 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
683 (match_operand:TF 2 "register_operand" "e")))]
684 "TARGET_FPU && TARGET_HARD_QUAD"
688 return \"fcmpeq\\t%0, %1, %2\";
689 return \"fcmpeq\\t%1, %2\";
691 [(set_attr "type" "fpcmp")])
693 (define_insn "*cmpsf_fp"
694 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
695 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
696 (match_operand:SF 2 "register_operand" "f")))]
701 return \"fcmps\\t%0, %1, %2\";
702 return \"fcmps\\t%1, %2\";
704 [(set_attr "type" "fpcmp")])
706 (define_insn "*cmpdf_fp"
707 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
708 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
709 (match_operand:DF 2 "register_operand" "e")))]
714 return \"fcmpd\\t%0, %1, %2\";
715 return \"fcmpd\\t%1, %2\";
717 [(set_attr "type" "fpcmp")])
719 (define_insn "*cmptf_fp"
720 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
721 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
722 (match_operand:TF 2 "register_operand" "e")))]
723 "TARGET_FPU && TARGET_HARD_QUAD"
727 return \"fcmpq\\t%0, %1, %2\";
728 return \"fcmpq\\t%1, %2\";
730 [(set_attr "type" "fpcmp")])
732 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
733 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
734 ;; the same code as v8 (the addx/subx method has more applications). The
735 ;; exception to this is "reg != 0" which can be done in one instruction on v9
736 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
739 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
740 ;; generate addcc/subcc instructions.
742 (define_expand "seqsi_special"
744 (xor:SI (match_operand:SI 1 "register_operand" "")
745 (match_operand:SI 2 "register_operand" "")))
746 (parallel [(set (match_operand:SI 0 "register_operand" "")
747 (eq:SI (match_dup 3) (const_int 0)))
748 (clobber (reg:CC 100))])]
750 "{ operands[3] = gen_reg_rtx (SImode); }")
752 (define_expand "seqdi_special"
754 (xor:DI (match_operand:DI 1 "register_operand" "")
755 (match_operand:DI 2 "register_operand" "")))
756 (set (match_operand:DI 0 "register_operand" "")
757 (eq:DI (match_dup 3) (const_int 0)))]
759 "{ operands[3] = gen_reg_rtx (DImode); }")
761 (define_expand "snesi_special"
763 (xor:SI (match_operand:SI 1 "register_operand" "")
764 (match_operand:SI 2 "register_operand" "")))
765 (parallel [(set (match_operand:SI 0 "register_operand" "")
766 (ne:SI (match_dup 3) (const_int 0)))
767 (clobber (reg:CC 100))])]
769 "{ operands[3] = gen_reg_rtx (SImode); }")
771 (define_expand "snedi_special"
773 (xor:DI (match_operand:DI 1 "register_operand" "")
774 (match_operand:DI 2 "register_operand" "")))
775 (set (match_operand:DI 0 "register_operand" "")
776 (ne:DI (match_dup 3) (const_int 0)))]
778 "{ operands[3] = gen_reg_rtx (DImode); }")
780 (define_expand "seqdi_special_trunc"
782 (xor:DI (match_operand:DI 1 "register_operand" "")
783 (match_operand:DI 2 "register_operand" "")))
784 (set (match_operand:SI 0 "register_operand" "")
785 (eq:SI (match_dup 3) (const_int 0)))]
787 "{ operands[3] = gen_reg_rtx (DImode); }")
789 (define_expand "snedi_special_trunc"
791 (xor:DI (match_operand:DI 1 "register_operand" "")
792 (match_operand:DI 2 "register_operand" "")))
793 (set (match_operand:SI 0 "register_operand" "")
794 (ne:SI (match_dup 3) (const_int 0)))]
796 "{ operands[3] = gen_reg_rtx (DImode); }")
798 (define_expand "seqsi_special_extend"
800 (xor:SI (match_operand:SI 1 "register_operand" "")
801 (match_operand:SI 2 "register_operand" "")))
802 (parallel [(set (match_operand:DI 0 "register_operand" "")
803 (eq:DI (match_dup 3) (const_int 0)))
804 (clobber (reg:CC 100))])]
806 "{ operands[3] = gen_reg_rtx (SImode); }")
808 (define_expand "snesi_special_extend"
810 (xor:SI (match_operand:SI 1 "register_operand" "")
811 (match_operand:SI 2 "register_operand" "")))
812 (parallel [(set (match_operand:DI 0 "register_operand" "")
813 (ne:DI (match_dup 3) (const_int 0)))
814 (clobber (reg:CC 100))])]
816 "{ operands[3] = gen_reg_rtx (SImode); }")
818 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
819 ;; However, the code handles both SImode and DImode.
821 [(set (match_operand:SI 0 "intreg_operand" "")
822 (eq:SI (match_dup 1) (const_int 0)))]
826 if (GET_MODE (sparc_compare_op0) == SImode)
830 if (GET_MODE (operands[0]) == SImode)
831 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
833 else if (! TARGET_ARCH64)
836 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
841 else if (GET_MODE (sparc_compare_op0) == DImode)
847 else if (GET_MODE (operands[0]) == SImode)
848 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
851 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
856 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
858 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
859 emit_jump_insn (gen_sne (operands[0]));
864 if (gen_v9_scc (EQ, operands))
871 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
872 ;; However, the code handles both SImode and DImode.
874 [(set (match_operand:SI 0 "intreg_operand" "")
875 (ne:SI (match_dup 1) (const_int 0)))]
879 if (GET_MODE (sparc_compare_op0) == SImode)
883 if (GET_MODE (operands[0]) == SImode)
884 pat = gen_snesi_special (operands[0], sparc_compare_op0,
886 else if (! TARGET_ARCH64)
889 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
894 else if (GET_MODE (sparc_compare_op0) == DImode)
900 else if (GET_MODE (operands[0]) == SImode)
901 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
904 pat = gen_snedi_special (operands[0], sparc_compare_op0,
909 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
911 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
912 emit_jump_insn (gen_sne (operands[0]));
917 if (gen_v9_scc (NE, operands))
925 [(set (match_operand:SI 0 "intreg_operand" "")
926 (gt:SI (match_dup 1) (const_int 0)))]
930 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
932 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
933 emit_jump_insn (gen_sne (operands[0]));
938 if (gen_v9_scc (GT, operands))
946 [(set (match_operand:SI 0 "intreg_operand" "")
947 (lt:SI (match_dup 1) (const_int 0)))]
951 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
953 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
954 emit_jump_insn (gen_sne (operands[0]));
959 if (gen_v9_scc (LT, operands))
967 [(set (match_operand:SI 0 "intreg_operand" "")
968 (ge:SI (match_dup 1) (const_int 0)))]
972 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
974 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
975 emit_jump_insn (gen_sne (operands[0]));
980 if (gen_v9_scc (GE, operands))
988 [(set (match_operand:SI 0 "intreg_operand" "")
989 (le:SI (match_dup 1) (const_int 0)))]
993 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
995 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
996 emit_jump_insn (gen_sne (operands[0]));
1001 if (gen_v9_scc (LE, operands))
1008 (define_expand "sgtu"
1009 [(set (match_operand:SI 0 "intreg_operand" "")
1010 (gtu:SI (match_dup 1) (const_int 0)))]
1018 /* We can do ltu easily, so if both operands are registers, swap them and
1020 if ((GET_CODE (sparc_compare_op0) == REG
1021 || GET_CODE (sparc_compare_op0) == SUBREG)
1022 && (GET_CODE (sparc_compare_op1) == REG
1023 || GET_CODE (sparc_compare_op1) == SUBREG))
1025 tem = sparc_compare_op0;
1026 sparc_compare_op0 = sparc_compare_op1;
1027 sparc_compare_op1 = tem;
1028 pat = gen_sltu (operands[0]);
1029 if (pat == NULL_RTX)
1037 if (gen_v9_scc (GTU, operands))
1043 (define_expand "sltu"
1044 [(set (match_operand:SI 0 "intreg_operand" "")
1045 (ltu:SI (match_dup 1) (const_int 0)))]
1051 if (gen_v9_scc (LTU, operands))
1054 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1057 (define_expand "sgeu"
1058 [(set (match_operand:SI 0 "intreg_operand" "")
1059 (geu:SI (match_dup 1) (const_int 0)))]
1065 if (gen_v9_scc (GEU, operands))
1068 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1071 (define_expand "sleu"
1072 [(set (match_operand:SI 0 "intreg_operand" "")
1073 (leu:SI (match_dup 1) (const_int 0)))]
1081 /* We can do geu easily, so if both operands are registers, swap them and
1083 if ((GET_CODE (sparc_compare_op0) == REG
1084 || GET_CODE (sparc_compare_op0) == SUBREG)
1085 && (GET_CODE (sparc_compare_op1) == REG
1086 || GET_CODE (sparc_compare_op1) == SUBREG))
1088 tem = sparc_compare_op0;
1089 sparc_compare_op0 = sparc_compare_op1;
1090 sparc_compare_op1 = tem;
1091 pat = gen_sgeu (operands[0]);
1092 if (pat == NULL_RTX)
1100 if (gen_v9_scc (LEU, operands))
1106 ;; Now the DEFINE_INSNs for the scc cases.
1108 ;; The SEQ and SNE patterns are special because they can be done
1109 ;; without any branching and do not involve a COMPARE. We want
1110 ;; them to always use the splitz below so the results can be
1113 (define_insn "*snesi_zero"
1114 [(set (match_operand:SI 0 "register_operand" "=r")
1115 (ne:SI (match_operand:SI 1 "register_operand" "r")
1117 (clobber (reg:CC 100))]
1120 [(set_attr "length" "2")])
1123 [(set (match_operand:SI 0 "register_operand" "")
1124 (ne:SI (match_operand:SI 1 "register_operand" "")
1126 (clobber (reg:CC 100))]
1128 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1130 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1133 (define_insn "*neg_snesi_zero"
1134 [(set (match_operand:SI 0 "register_operand" "=r")
1135 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1137 (clobber (reg:CC 100))]
1140 [(set_attr "length" "2")])
1143 [(set (match_operand:SI 0 "register_operand" "")
1144 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1146 (clobber (reg:CC 100))]
1148 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1150 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1153 (define_insn "*snesi_zero_extend"
1154 [(set (match_operand:DI 0 "register_operand" "=r")
1155 (ne:DI (match_operand:SI 1 "register_operand" "r")
1157 (clobber (reg:CC 100))]
1160 [(set_attr "type" "unary")
1161 (set_attr "length" "2")])
1164 [(set (match_operand:DI 0 "register_operand" "")
1165 (ne:DI (match_operand:SI 1 "register_operand" "")
1167 (clobber (reg:CC 100))]
1169 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1171 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1173 (ltu:SI (reg:CC_NOOV 100)
1177 (define_insn "*snedi_zero"
1178 [(set (match_operand:DI 0 "register_operand" "=&r")
1179 (ne:DI (match_operand:DI 1 "register_operand" "r")
1183 [(set_attr "type" "cmove")
1184 (set_attr "length" "2")])
1187 [(set (match_operand:DI 0 "register_operand" "")
1188 (ne:DI (match_operand:DI 1 "register_operand" "")
1191 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1192 [(set (match_dup 0) (const_int 0))
1193 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1199 (define_insn "*neg_snedi_zero"
1200 [(set (match_operand:DI 0 "register_operand" "=&r")
1201 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1205 [(set_attr "type" "cmove")
1206 (set_attr "length" "2")])
1209 [(set (match_operand:DI 0 "register_operand" "")
1210 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1213 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1214 [(set (match_dup 0) (const_int 0))
1215 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1221 (define_insn "*snedi_zero_trunc"
1222 [(set (match_operand:SI 0 "register_operand" "=&r")
1223 (ne:SI (match_operand:DI 1 "register_operand" "r")
1227 [(set_attr "type" "cmove")
1228 (set_attr "length" "2")])
1231 [(set (match_operand:SI 0 "register_operand" "")
1232 (ne:SI (match_operand:DI 1 "register_operand" "")
1235 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1236 [(set (match_dup 0) (const_int 0))
1237 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1243 (define_insn "*seqsi_zero"
1244 [(set (match_operand:SI 0 "register_operand" "=r")
1245 (eq:SI (match_operand:SI 1 "register_operand" "r")
1247 (clobber (reg:CC 100))]
1250 [(set_attr "length" "2")])
1253 [(set (match_operand:SI 0 "register_operand" "")
1254 (eq:SI (match_operand:SI 1 "register_operand" "")
1256 (clobber (reg:CC 100))]
1258 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1260 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1263 (define_insn "*neg_seqsi_zero"
1264 [(set (match_operand:SI 0 "register_operand" "=r")
1265 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1267 (clobber (reg:CC 100))]
1270 [(set_attr "length" "2")])
1273 [(set (match_operand:SI 0 "register_operand" "")
1274 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1276 (clobber (reg:CC 100))]
1278 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1280 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1283 (define_insn "*seqsi_zero_extend"
1284 [(set (match_operand:DI 0 "register_operand" "=r")
1285 (eq:DI (match_operand:SI 1 "register_operand" "r")
1287 (clobber (reg:CC 100))]
1290 [(set_attr "type" "unary")
1291 (set_attr "length" "2")])
1294 [(set (match_operand:DI 0 "register_operand" "")
1295 (eq:DI (match_operand:SI 1 "register_operand" "")
1297 (clobber (reg:CC 100))]
1299 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1301 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1303 (ltu:SI (reg:CC_NOOV 100)
1307 (define_insn "*seqdi_zero"
1308 [(set (match_operand:DI 0 "register_operand" "=&r")
1309 (eq:DI (match_operand:DI 1 "register_operand" "r")
1313 [(set_attr "type" "cmove")
1314 (set_attr "length" "2")])
1317 [(set (match_operand:DI 0 "register_operand" "")
1318 (eq:DI (match_operand:DI 1 "register_operand" "")
1321 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1322 [(set (match_dup 0) (const_int 0))
1323 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1329 (define_insn "*neg_seqdi_zero"
1330 [(set (match_operand:DI 0 "register_operand" "=&r")
1331 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1335 [(set_attr "type" "cmove")
1336 (set_attr "length" "2")])
1339 [(set (match_operand:DI 0 "register_operand" "")
1340 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1343 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1344 [(set (match_dup 0) (const_int 0))
1345 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1351 (define_insn "*seqdi_zero_trunc"
1352 [(set (match_operand:SI 0 "register_operand" "=&r")
1353 (eq:SI (match_operand:DI 1 "register_operand" "r")
1357 [(set_attr "type" "cmove")
1358 (set_attr "length" "2")])
1361 [(set (match_operand:SI 0 "register_operand" "")
1362 (eq:SI (match_operand:DI 1 "register_operand" "")
1365 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1366 [(set (match_dup 0) (const_int 0))
1367 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1373 ;; We can also do (x + (i == 0)) and related, so put them in.
1374 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1377 (define_insn "*x_plus_i_ne_0"
1378 [(set (match_operand:SI 0 "register_operand" "=r")
1379 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1381 (match_operand:SI 2 "register_operand" "r")))
1382 (clobber (reg:CC 100))]
1385 [(set_attr "length" "2")])
1388 [(set (match_operand:SI 0 "register_operand" "")
1389 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1391 (match_operand:SI 2 "register_operand" "")))
1392 (clobber (reg:CC 100))]
1394 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1396 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1400 (define_insn "*x_minus_i_ne_0"
1401 [(set (match_operand:SI 0 "register_operand" "=r")
1402 (minus:SI (match_operand:SI 2 "register_operand" "r")
1403 (ne:SI (match_operand:SI 1 "register_operand" "r")
1405 (clobber (reg:CC 100))]
1408 [(set_attr "length" "2")])
1411 [(set (match_operand:SI 0 "register_operand" "")
1412 (minus:SI (match_operand:SI 2 "register_operand" "")
1413 (ne:SI (match_operand:SI 1 "register_operand" "")
1415 (clobber (reg:CC 100))]
1417 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1419 (set (match_dup 0) (minus:SI (match_dup 2)
1420 (ltu:SI (reg:CC 100) (const_int 0))))]
1423 (define_insn "*x_plus_i_eq_0"
1424 [(set (match_operand:SI 0 "register_operand" "=r")
1425 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1427 (match_operand:SI 2 "register_operand" "r")))
1428 (clobber (reg:CC 100))]
1431 [(set_attr "length" "2")])
1434 [(set (match_operand:SI 0 "register_operand" "")
1435 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1437 (match_operand:SI 2 "register_operand" "")))
1438 (clobber (reg:CC 100))]
1440 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1442 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1446 (define_insn "*x_minus_i_eq_0"
1447 [(set (match_operand:SI 0 "register_operand" "=r")
1448 (minus:SI (match_operand:SI 2 "register_operand" "r")
1449 (eq:SI (match_operand:SI 1 "register_operand" "r")
1451 (clobber (reg:CC 100))]
1454 [(set_attr "length" "2")])
1457 [(set (match_operand:SI 0 "register_operand" "")
1458 (minus:SI (match_operand:SI 2 "register_operand" "")
1459 (eq:SI (match_operand:SI 1 "register_operand" "")
1461 (clobber (reg:CC 100))]
1463 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1465 (set (match_dup 0) (minus:SI (match_dup 2)
1466 (geu:SI (reg:CC 100) (const_int 0))))]
1469 ;; We can also do GEU and LTU directly, but these operate after a compare.
1470 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1473 (define_insn "*sltu_insn"
1474 [(set (match_operand:SI 0 "register_operand" "=r")
1475 (ltu:SI (reg:CC 100) (const_int 0)))]
1477 "addx\\t%%g0, 0, %0"
1478 [(set_attr "type" "misc")
1479 (set_attr "length" "1")])
1481 (define_insn "*neg_sltu_insn"
1482 [(set (match_operand:SI 0 "register_operand" "=r")
1483 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1485 "subx\\t%%g0, 0, %0"
1486 [(set_attr "type" "misc")
1487 (set_attr "length" "1")])
1489 ;; ??? Combine should canonicalize these next two to the same pattern.
1490 (define_insn "*neg_sltu_minus_x"
1491 [(set (match_operand:SI 0 "register_operand" "=r")
1492 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1493 (match_operand:SI 1 "arith_operand" "rI")))]
1495 "subx\\t%%g0, %1, %0"
1496 [(set_attr "type" "misc")
1497 (set_attr "length" "1")])
1499 (define_insn "*neg_sltu_plus_x"
1500 [(set (match_operand:SI 0 "register_operand" "=r")
1501 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1502 (match_operand:SI 1 "arith_operand" "rI"))))]
1504 "subx\\t%%g0, %1, %0"
1505 [(set_attr "type" "misc")
1506 (set_attr "length" "1")])
1508 (define_insn "*sgeu_insn"
1509 [(set (match_operand:SI 0 "register_operand" "=r")
1510 (geu:SI (reg:CC 100) (const_int 0)))]
1512 "subx\\t%%g0, -1, %0"
1513 [(set_attr "type" "misc")
1514 (set_attr "length" "1")])
1516 (define_insn "*neg_sgeu_insn"
1517 [(set (match_operand:SI 0 "register_operand" "=r")
1518 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1520 "addx\\t%%g0, -1, %0"
1521 [(set_attr "type" "misc")
1522 (set_attr "length" "1")])
1524 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1525 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1528 (define_insn "*sltu_plus_x"
1529 [(set (match_operand:SI 0 "register_operand" "=r")
1530 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1531 (match_operand:SI 1 "arith_operand" "rI")))]
1533 "addx\\t%%g0, %1, %0"
1534 [(set_attr "type" "misc")
1535 (set_attr "length" "1")])
1537 (define_insn "*sltu_plus_x_plus_y"
1538 [(set (match_operand:SI 0 "register_operand" "=r")
1539 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1540 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1541 (match_operand:SI 2 "arith_operand" "rI"))))]
1544 [(set_attr "type" "misc")
1545 (set_attr "length" "1")])
1547 (define_insn "*x_minus_sltu"
1548 [(set (match_operand:SI 0 "register_operand" "=r")
1549 (minus:SI (match_operand:SI 1 "register_operand" "r")
1550 (ltu:SI (reg:CC 100) (const_int 0))))]
1553 [(set_attr "type" "misc")
1554 (set_attr "length" "1")])
1556 ;; ??? Combine should canonicalize these next two to the same pattern.
1557 (define_insn "*x_minus_y_minus_sltu"
1558 [(set (match_operand:SI 0 "register_operand" "=r")
1559 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1560 (match_operand:SI 2 "arith_operand" "rI"))
1561 (ltu:SI (reg:CC 100) (const_int 0))))]
1563 "subx\\t%r1, %2, %0"
1564 [(set_attr "type" "misc")
1565 (set_attr "length" "1")])
1567 (define_insn "*x_minus_sltu_plus_y"
1568 [(set (match_operand:SI 0 "register_operand" "=r")
1569 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1570 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1571 (match_operand:SI 2 "arith_operand" "rI"))))]
1573 "subx\\t%r1, %2, %0"
1574 [(set_attr "type" "misc")
1575 (set_attr "length" "1")])
1577 (define_insn "*sgeu_plus_x"
1578 [(set (match_operand:SI 0 "register_operand" "=r")
1579 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1580 (match_operand:SI 1 "register_operand" "r")))]
1583 [(set_attr "type" "misc")
1584 (set_attr "length" "1")])
1586 (define_insn "*x_minus_sgeu"
1587 [(set (match_operand:SI 0 "register_operand" "=r")
1588 (minus:SI (match_operand:SI 1 "register_operand" "r")
1589 (geu:SI (reg:CC 100) (const_int 0))))]
1592 [(set_attr "type" "misc")
1593 (set_attr "length" "1")])
1596 [(set (match_operand:SI 0 "register_operand" "=r")
1597 (match_operator:SI 2 "noov_compare_op"
1598 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1600 ;; 32 bit LTU/GEU are better implemented using addx/subx
1601 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1602 && (GET_MODE (operands[1]) == CCXmode
1603 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1604 [(set (match_dup 0) (const_int 0))
1606 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1612 ;; These control RTL generation for conditional jump insns
1614 ;; The quad-word fp compare library routines all return nonzero to indicate
1615 ;; true, which is different from the equivalent libgcc routines, so we must
1616 ;; handle them specially here.
1618 (define_expand "beq"
1620 (if_then_else (eq (match_dup 1) (const_int 0))
1621 (label_ref (match_operand 0 "" ""))
1626 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1627 && GET_CODE (sparc_compare_op0) == REG
1628 && GET_MODE (sparc_compare_op0) == DImode)
1630 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1633 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1635 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1636 emit_jump_insn (gen_bne (operands[0]));
1639 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1642 (define_expand "bne"
1644 (if_then_else (ne (match_dup 1) (const_int 0))
1645 (label_ref (match_operand 0 "" ""))
1650 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1651 && GET_CODE (sparc_compare_op0) == REG
1652 && GET_MODE (sparc_compare_op0) == DImode)
1654 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1657 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1659 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1660 emit_jump_insn (gen_bne (operands[0]));
1663 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1666 (define_expand "bgt"
1668 (if_then_else (gt (match_dup 1) (const_int 0))
1669 (label_ref (match_operand 0 "" ""))
1674 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1675 && GET_CODE (sparc_compare_op0) == REG
1676 && GET_MODE (sparc_compare_op0) == DImode)
1678 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1681 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1683 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1684 emit_jump_insn (gen_bne (operands[0]));
1687 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1690 (define_expand "bgtu"
1692 (if_then_else (gtu (match_dup 1) (const_int 0))
1693 (label_ref (match_operand 0 "" ""))
1697 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1700 (define_expand "blt"
1702 (if_then_else (lt (match_dup 1) (const_int 0))
1703 (label_ref (match_operand 0 "" ""))
1708 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1709 && GET_CODE (sparc_compare_op0) == REG
1710 && GET_MODE (sparc_compare_op0) == DImode)
1712 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1715 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1717 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1718 emit_jump_insn (gen_bne (operands[0]));
1721 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1724 (define_expand "bltu"
1726 (if_then_else (ltu (match_dup 1) (const_int 0))
1727 (label_ref (match_operand 0 "" ""))
1731 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1734 (define_expand "bge"
1736 (if_then_else (ge (match_dup 1) (const_int 0))
1737 (label_ref (match_operand 0 "" ""))
1742 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1743 && GET_CODE (sparc_compare_op0) == REG
1744 && GET_MODE (sparc_compare_op0) == DImode)
1746 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1749 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1751 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1752 emit_jump_insn (gen_bne (operands[0]));
1755 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1758 (define_expand "bgeu"
1760 (if_then_else (geu (match_dup 1) (const_int 0))
1761 (label_ref (match_operand 0 "" ""))
1765 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1768 (define_expand "ble"
1770 (if_then_else (le (match_dup 1) (const_int 0))
1771 (label_ref (match_operand 0 "" ""))
1776 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1777 && GET_CODE (sparc_compare_op0) == REG
1778 && GET_MODE (sparc_compare_op0) == DImode)
1780 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1783 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1785 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1786 emit_jump_insn (gen_bne (operands[0]));
1789 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1792 (define_expand "bleu"
1794 (if_then_else (leu (match_dup 1) (const_int 0))
1795 (label_ref (match_operand 0 "" ""))
1799 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1802 (define_expand "bunordered"
1804 (if_then_else (unordered (match_dup 1) (const_int 0))
1805 (label_ref (match_operand 0 "" ""))
1810 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1812 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1814 emit_jump_insn (gen_beq (operands[0]));
1817 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1821 (define_expand "bordered"
1823 (if_then_else (ordered (match_dup 1) (const_int 0))
1824 (label_ref (match_operand 0 "" ""))
1829 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1831 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1832 emit_jump_insn (gen_bne (operands[0]));
1835 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1839 (define_expand "bungt"
1841 (if_then_else (ungt (match_dup 1) (const_int 0))
1842 (label_ref (match_operand 0 "" ""))
1847 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1849 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1850 emit_jump_insn (gen_bgt (operands[0]));
1853 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1856 (define_expand "bunlt"
1858 (if_then_else (unlt (match_dup 1) (const_int 0))
1859 (label_ref (match_operand 0 "" ""))
1864 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1866 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1867 emit_jump_insn (gen_bne (operands[0]));
1870 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1873 (define_expand "buneq"
1875 (if_then_else (uneq (match_dup 1) (const_int 0))
1876 (label_ref (match_operand 0 "" ""))
1881 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1883 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1884 emit_jump_insn (gen_beq (operands[0]));
1887 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1890 (define_expand "bunge"
1892 (if_then_else (unge (match_dup 1) (const_int 0))
1893 (label_ref (match_operand 0 "" ""))
1898 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1900 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1901 emit_jump_insn (gen_bne (operands[0]));
1904 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1907 (define_expand "bunle"
1909 (if_then_else (unle (match_dup 1) (const_int 0))
1910 (label_ref (match_operand 0 "" ""))
1915 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1917 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1918 emit_jump_insn (gen_bne (operands[0]));
1921 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1924 (define_expand "bltgt"
1926 (if_then_else (ltgt (match_dup 1) (const_int 0))
1927 (label_ref (match_operand 0 "" ""))
1932 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1934 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1935 emit_jump_insn (gen_bne (operands[0]));
1938 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1941 ;; Now match both normal and inverted jump.
1943 ;; XXX fpcmp nop braindamage
1944 (define_insn "*normal_branch"
1946 (if_then_else (match_operator 0 "noov_compare_op"
1947 [(reg 100) (const_int 0)])
1948 (label_ref (match_operand 1 "" ""))
1953 return output_cbranch (operands[0], 1, 0,
1954 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1955 ! final_sequence, insn);
1957 [(set_attr "type" "branch")])
1959 ;; XXX fpcmp nop braindamage
1960 (define_insn "*inverted_branch"
1962 (if_then_else (match_operator 0 "noov_compare_op"
1963 [(reg 100) (const_int 0)])
1965 (label_ref (match_operand 1 "" ""))))]
1969 return output_cbranch (operands[0], 1, 1,
1970 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1971 ! final_sequence, insn);
1973 [(set_attr "type" "branch")])
1975 ;; XXX fpcmp nop braindamage
1976 (define_insn "*normal_fp_branch"
1978 (if_then_else (match_operator 1 "comparison_operator"
1979 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1981 (label_ref (match_operand 2 "" ""))
1986 return output_cbranch (operands[1], 2, 0,
1987 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1988 ! final_sequence, insn);
1990 [(set_attr "type" "branch")])
1992 ;; XXX fpcmp nop braindamage
1993 (define_insn "*inverted_fp_branch"
1995 (if_then_else (match_operator 1 "comparison_operator"
1996 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1999 (label_ref (match_operand 2 "" ""))))]
2003 return output_cbranch (operands[1], 2, 1,
2004 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2005 ! final_sequence, insn);
2007 [(set_attr "type" "branch")])
2009 ;; XXX fpcmp nop braindamage
2010 (define_insn "*normal_fpe_branch"
2012 (if_then_else (match_operator 1 "comparison_operator"
2013 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2015 (label_ref (match_operand 2 "" ""))
2020 return output_cbranch (operands[1], 2, 0,
2021 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2022 ! final_sequence, insn);
2024 [(set_attr "type" "branch")])
2026 ;; XXX fpcmp nop braindamage
2027 (define_insn "*inverted_fpe_branch"
2029 (if_then_else (match_operator 1 "comparison_operator"
2030 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2033 (label_ref (match_operand 2 "" ""))))]
2037 return output_cbranch (operands[1], 2, 1,
2038 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2039 ! final_sequence, insn);
2041 [(set_attr "type" "branch")])
2043 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
2044 ;; in the architecture.
2046 ;; There are no 32 bit brreg insns.
2049 (define_insn "*normal_int_branch_sp64"
2051 (if_then_else (match_operator 0 "v9_regcmp_op"
2052 [(match_operand:DI 1 "register_operand" "r")
2054 (label_ref (match_operand 2 "" ""))
2059 return output_v9branch (operands[0], 1, 2, 0,
2060 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2061 ! final_sequence, insn);
2063 [(set_attr "type" "branch")])
2066 (define_insn "*inverted_int_branch_sp64"
2068 (if_then_else (match_operator 0 "v9_regcmp_op"
2069 [(match_operand:DI 1 "register_operand" "r")
2072 (label_ref (match_operand 2 "" ""))))]
2076 return output_v9branch (operands[0], 1, 2, 1,
2077 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2078 ! final_sequence, insn);
2080 [(set_attr "type" "branch")])
2082 ;; Load program counter insns.
2084 (define_insn "get_pc"
2085 [(clobber (reg:SI 15))
2086 (set (match_operand 0 "register_operand" "=r")
2087 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2088 "flag_pic && REGNO (operands[0]) == 23"
2089 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2090 [(set_attr "length" "3")])
2092 ;; Currently unused...
2093 ;; (define_insn "get_pc_via_rdpc"
2094 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2097 ;; [(set_attr "type" "move")])
2100 ;; Move instructions
2102 (define_expand "movqi"
2103 [(set (match_operand:QI 0 "general_operand" "")
2104 (match_operand:QI 1 "general_operand" ""))]
2108 /* Working with CONST_INTs is easier, so convert
2109 a double if needed. */
2110 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2112 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff);
2114 else if (GET_CODE (operands[1]) == CONST_INT)
2116 /* And further, we know for all QI cases that only the
2117 low byte is significant, which we can always process
2118 in a single insn. So mask it now. */
2119 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
2122 /* Handle sets of MEM first. */
2123 if (GET_CODE (operands[0]) == MEM)
2125 if (reg_or_0_operand (operands[1], QImode))
2128 if (! reload_in_progress)
2130 operands[0] = validize_mem (operands[0]);
2131 operands[1] = force_reg (QImode, operands[1]);
2135 /* Fixup PIC cases. */
2138 if (CONSTANT_P (operands[1])
2139 && pic_address_needs_scratch (operands[1]))
2140 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2142 if (symbolic_operand (operands[1], QImode))
2144 operands[1] = legitimize_pic_address (operands[1],
2146 (reload_in_progress ?
2153 /* All QI constants require only one insn, so proceed. */
2159 (define_insn "*movqi_insn"
2160 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2161 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2162 "(register_operand (operands[0], QImode)
2163 || reg_or_0_operand (operands[1], QImode))"
2168 [(set_attr "type" "move,load,store")
2169 (set_attr "length" "1")])
2171 (define_expand "movhi"
2172 [(set (match_operand:HI 0 "general_operand" "")
2173 (match_operand:HI 1 "general_operand" ""))]
2177 /* Working with CONST_INTs is easier, so convert
2178 a double if needed. */
2179 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2180 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2182 /* Handle sets of MEM first. */
2183 if (GET_CODE (operands[0]) == MEM)
2185 if (reg_or_0_operand (operands[1], HImode))
2188 if (! reload_in_progress)
2190 operands[0] = validize_mem (operands[0]);
2191 operands[1] = force_reg (HImode, operands[1]);
2195 /* Fixup PIC cases. */
2198 if (CONSTANT_P (operands[1])
2199 && pic_address_needs_scratch (operands[1]))
2200 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2202 if (symbolic_operand (operands[1], HImode))
2204 operands[1] = legitimize_pic_address (operands[1],
2206 (reload_in_progress ?
2213 /* This makes sure we will not get rematched due to splittage. */
2214 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2216 else if (CONSTANT_P (operands[1])
2217 && GET_CODE (operands[1]) != HIGH
2218 && GET_CODE (operands[1]) != LO_SUM)
2220 sparc_emit_set_const32 (operands[0], operands[1]);
2227 (define_insn "*movhi_const64_special"
2228 [(set (match_operand:HI 0 "register_operand" "=r")
2229 (match_operand:HI 1 "const64_high_operand" ""))]
2231 "sethi\\t%%hi(%a1), %0"
2232 [(set_attr "type" "move")
2233 (set_attr "length" "1")])
2235 (define_insn "*movhi_insn"
2236 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2237 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2238 "(register_operand (operands[0], HImode)
2239 || reg_or_0_operand (operands[1], HImode))"
2242 sethi\\t%%hi(%a1), %0
2245 [(set_attr "type" "move,move,load,store")
2246 (set_attr "length" "1")])
2248 ;; We always work with constants here.
2249 (define_insn "*movhi_lo_sum"
2250 [(set (match_operand:HI 0 "register_operand" "=r")
2251 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2252 (match_operand:HI 2 "arith_operand" "I")))]
2255 [(set_attr "type" "ialu")
2256 (set_attr "length" "1")])
2258 (define_expand "movsi"
2259 [(set (match_operand:SI 0 "general_operand" "")
2260 (match_operand:SI 1 "general_operand" ""))]
2264 /* Working with CONST_INTs is easier, so convert
2265 a double if needed. */
2266 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2267 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2269 /* Handle sets of MEM first. */
2270 if (GET_CODE (operands[0]) == MEM)
2272 if (reg_or_0_operand (operands[1], SImode))
2275 if (! reload_in_progress)
2277 operands[0] = validize_mem (operands[0]);
2278 operands[1] = force_reg (SImode, operands[1]);
2282 /* Fixup PIC cases. */
2285 if (CONSTANT_P (operands[1])
2286 && pic_address_needs_scratch (operands[1]))
2287 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2289 if (GET_CODE (operands[1]) == LABEL_REF)
2292 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2296 if (symbolic_operand (operands[1], SImode))
2298 operands[1] = legitimize_pic_address (operands[1],
2300 (reload_in_progress ?
2307 /* If we are trying to toss an integer constant into the
2308 FPU registers, force it into memory. */
2309 if (GET_CODE (operands[0]) == REG
2310 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2311 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2312 && CONSTANT_P (operands[1]))
2313 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2316 /* This makes sure we will not get rematched due to splittage. */
2317 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2319 else if (CONSTANT_P (operands[1])
2320 && GET_CODE (operands[1]) != HIGH
2321 && GET_CODE (operands[1]) != LO_SUM)
2323 sparc_emit_set_const32 (operands[0], operands[1]);
2330 ;; This is needed to show CSE exactly which bits are set
2331 ;; in a 64-bit register by sethi instructions.
2332 (define_insn "*movsi_const64_special"
2333 [(set (match_operand:SI 0 "register_operand" "=r")
2334 (match_operand:SI 1 "const64_high_operand" ""))]
2336 "sethi\\t%%hi(%a1), %0"
2337 [(set_attr "type" "move")
2338 (set_attr "length" "1")])
2340 (define_insn "*movsi_insn"
2341 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2342 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2343 "(register_operand (operands[0], SImode)
2344 || reg_or_0_operand (operands[1], SImode))"
2348 sethi\\t%%hi(%a1), %0
2355 [(set_attr "type" "move,fpmove,move,move,load,fpload,store,fpstore,fpmove")
2356 (set_attr "length" "1")])
2358 (define_insn "*movsi_lo_sum"
2359 [(set (match_operand:SI 0 "register_operand" "=r")
2360 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2361 (match_operand:SI 2 "immediate_operand" "in")))]
2363 "or\\t%1, %%lo(%a2), %0"
2364 [(set_attr "type" "ialu")
2365 (set_attr "length" "1")])
2367 (define_insn "*movsi_high"
2368 [(set (match_operand:SI 0 "register_operand" "=r")
2369 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2371 "sethi\\t%%hi(%a1), %0"
2372 [(set_attr "type" "move")
2373 (set_attr "length" "1")])
2375 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2376 ;; so that CSE won't optimize the address computation away.
2377 (define_insn "movsi_lo_sum_pic"
2378 [(set (match_operand:SI 0 "register_operand" "=r")
2379 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2380 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2382 "or\\t%1, %%lo(%a2), %0"
2383 [(set_attr "type" "ialu")
2384 (set_attr "length" "1")])
2386 (define_insn "movsi_high_pic"
2387 [(set (match_operand:SI 0 "register_operand" "=r")
2388 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2389 "flag_pic && check_pic (1)"
2390 "sethi\\t%%hi(%a1), %0"
2391 [(set_attr "type" "move")
2392 (set_attr "length" "1")])
2394 (define_expand "movsi_pic_label_ref"
2395 [(set (match_dup 3) (high:SI
2396 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2398 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2399 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2400 (set (match_operand:SI 0 "register_operand" "=r")
2401 (minus:SI (match_dup 5) (match_dup 4)))]
2405 current_function_uses_pic_offset_table = 1;
2406 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2409 operands[3] = operands[0];
2410 operands[4] = operands[0];
2414 operands[3] = gen_reg_rtx (SImode);
2415 operands[4] = gen_reg_rtx (SImode);
2417 operands[5] = pic_offset_table_rtx;
2420 (define_insn "*movsi_high_pic_label_ref"
2421 [(set (match_operand:SI 0 "register_operand" "=r")
2423 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2424 (match_operand:SI 2 "" "")] 5)))]
2426 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2427 [(set_attr "type" "move")
2428 (set_attr "length" "1")])
2430 (define_insn "*movsi_lo_sum_pic_label_ref"
2431 [(set (match_operand:SI 0 "register_operand" "=r")
2432 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2433 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2434 (match_operand:SI 3 "" "")] 5)))]
2436 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2437 [(set_attr "type" "ialu")
2438 (set_attr "length" "1")])
2440 (define_expand "movdi"
2441 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2442 (match_operand:DI 1 "general_operand" ""))]
2446 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2447 if (GET_CODE (operands[1]) == CONST_DOUBLE
2448 #if HOST_BITS_PER_WIDE_INT == 32
2449 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2450 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2451 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2452 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2455 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2457 /* Handle MEM cases first. */
2458 if (GET_CODE (operands[0]) == MEM)
2460 /* If it's a REG, we can always do it.
2461 The const zero case is more complex, on v9
2462 we can always perform it. */
2463 if (register_operand (operands[1], DImode)
2465 && (operands[1] == const0_rtx)))
2468 if (! reload_in_progress)
2470 operands[0] = validize_mem (operands[0]);
2471 operands[1] = force_reg (DImode, operands[1]);
2477 if (CONSTANT_P (operands[1])
2478 && pic_address_needs_scratch (operands[1]))
2479 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2481 if (GET_CODE (operands[1]) == LABEL_REF)
2483 if (! TARGET_ARCH64)
2485 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2489 if (symbolic_operand (operands[1], DImode))
2491 operands[1] = legitimize_pic_address (operands[1],
2493 (reload_in_progress ?
2500 /* If we are trying to toss an integer constant into the
2501 FPU registers, force it into memory. */
2502 if (GET_CODE (operands[0]) == REG
2503 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2504 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2505 && CONSTANT_P (operands[1]))
2506 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2509 /* This makes sure we will not get rematched due to splittage. */
2510 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2512 else if (TARGET_ARCH64
2513 && CONSTANT_P (operands[1])
2514 && GET_CODE (operands[1]) != HIGH
2515 && GET_CODE (operands[1]) != LO_SUM)
2517 sparc_emit_set_const64 (operands[0], operands[1]);
2525 ;; Be careful, fmovd does not exist when !arch64.
2526 ;; We match MEM moves directly when we have correct even
2527 ;; numbered registers, but fall into splits otherwise.
2528 ;; The constraint ordering here is really important to
2529 ;; avoid insane problems in reload, especially for patterns
2532 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2533 ;; (const_int -5016)))
2536 (define_insn "*movdi_insn_sp32"
2537 [(set (match_operand:DI 0 "nonimmediate_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2538 (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))]
2540 (register_operand (operands[0], DImode)
2541 || register_operand (operands[1], DImode))"
2554 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2555 (set_attr "length" "1,1,2,2,2,2,1,1,2,2,2")])
2557 ;; The following are generated by sparc_emit_set_const64
2558 (define_insn "*movdi_sp64_dbl"
2559 [(set (match_operand:DI 0 "register_operand" "=r")
2560 (match_operand:DI 1 "const64_operand" ""))]
2562 && HOST_BITS_PER_WIDE_INT != 64)"
2564 [(set_attr "type" "move")
2565 (set_attr "length" "1")])
2567 ;; This is needed to show CSE exactly which bits are set
2568 ;; in a 64-bit register by sethi instructions.
2569 (define_insn "*movdi_const64_special"
2570 [(set (match_operand:DI 0 "register_operand" "=r")
2571 (match_operand:DI 1 "const64_high_operand" ""))]
2573 "sethi\\t%%hi(%a1), %0"
2574 [(set_attr "type" "move")
2575 (set_attr "length" "1")])
2577 (define_insn "*movdi_insn_sp64_novis"
2578 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
2579 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e"))]
2580 "TARGET_ARCH64 && ! TARGET_VIS
2581 && (register_operand (operands[0], DImode)
2582 || reg_or_0_operand (operands[1], DImode))"
2585 sethi\\t%%hi(%a1), %0
2592 [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore")
2593 (set_attr "length" "1")])
2595 (define_insn "*movdi_insn_sp64_vis"
2596 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2597 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))]
2598 "TARGET_ARCH64 && TARGET_VIS &&
2599 (register_operand (operands[0], DImode)
2600 || reg_or_0_operand (operands[1], DImode))"
2603 sethi\\t%%hi(%a1), %0
2611 [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore,fpmove")
2612 (set_attr "length" "1")])
2614 (define_expand "movdi_pic_label_ref"
2615 [(set (match_dup 3) (high:DI
2616 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2618 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2619 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2620 (set (match_operand:DI 0 "register_operand" "=r")
2621 (minus:DI (match_dup 5) (match_dup 4)))]
2622 "TARGET_ARCH64 && flag_pic"
2625 current_function_uses_pic_offset_table = 1;
2626 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2629 operands[3] = operands[0];
2630 operands[4] = operands[0];
2634 operands[3] = gen_reg_rtx (DImode);
2635 operands[4] = gen_reg_rtx (DImode);
2637 operands[5] = pic_offset_table_rtx;
2640 (define_insn "*movdi_high_pic_label_ref"
2641 [(set (match_operand:DI 0 "register_operand" "=r")
2643 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2644 (match_operand:DI 2 "" "")] 5)))]
2645 "TARGET_ARCH64 && flag_pic"
2646 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2647 [(set_attr "type" "move")
2648 (set_attr "length" "1")])
2650 (define_insn "*movdi_lo_sum_pic_label_ref"
2651 [(set (match_operand:DI 0 "register_operand" "=r")
2652 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2653 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2654 (match_operand:DI 3 "" "")] 5)))]
2655 "TARGET_ARCH64 && flag_pic"
2656 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2657 [(set_attr "type" "ialu")
2658 (set_attr "length" "1")])
2660 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2661 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2663 (define_insn "movdi_lo_sum_pic"
2664 [(set (match_operand:DI 0 "register_operand" "=r")
2665 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2666 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2667 "TARGET_ARCH64 && flag_pic"
2668 "or\\t%1, %%lo(%a2), %0"
2669 [(set_attr "type" "ialu")
2670 (set_attr "length" "1")])
2672 (define_insn "movdi_high_pic"
2673 [(set (match_operand:DI 0 "register_operand" "=r")
2674 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2675 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2676 "sethi\\t%%hi(%a1), %0"
2677 [(set_attr "type" "move")
2678 (set_attr "length" "1")])
2680 (define_insn "*sethi_di_medlow_embmedany_pic"
2681 [(set (match_operand:DI 0 "register_operand" "=r")
2682 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2683 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2684 "sethi\\t%%hi(%a1), %0"
2685 [(set_attr "type" "move")
2686 (set_attr "length" "1")])
2688 (define_insn "*sethi_di_medlow"
2689 [(set (match_operand:DI 0 "register_operand" "=r")
2690 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2691 "TARGET_CM_MEDLOW && check_pic (1)"
2692 "sethi\\t%%hi(%a1), %0"
2693 [(set_attr "type" "move")
2694 (set_attr "length" "1")])
2696 (define_insn "*losum_di_medlow"
2697 [(set (match_operand:DI 0 "register_operand" "=r")
2698 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2699 (match_operand:DI 2 "symbolic_operand" "")))]
2701 "or\\t%1, %%lo(%a2), %0"
2702 [(set_attr "type" "ialu")
2703 (set_attr "length" "1")])
2705 (define_insn "seth44"
2706 [(set (match_operand:DI 0 "register_operand" "=r")
2707 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2709 "sethi\\t%%h44(%a1), %0"
2710 [(set_attr "type" "move")
2711 (set_attr "length" "1")])
2713 (define_insn "setm44"
2714 [(set (match_operand:DI 0 "register_operand" "=r")
2715 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2716 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2718 "or\\t%1, %%m44(%a2), %0"
2719 [(set_attr "type" "move")
2720 (set_attr "length" "1")])
2722 (define_insn "setl44"
2723 [(set (match_operand:DI 0 "register_operand" "=r")
2724 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2725 (match_operand:DI 2 "symbolic_operand" "")))]
2727 "or\\t%1, %%l44(%a2), %0"
2728 [(set_attr "type" "ialu")
2729 (set_attr "length" "1")])
2731 (define_insn "sethh"
2732 [(set (match_operand:DI 0 "register_operand" "=r")
2733 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2735 "sethi\\t%%hh(%a1), %0"
2736 [(set_attr "type" "move")
2737 (set_attr "length" "1")])
2739 (define_insn "setlm"
2740 [(set (match_operand:DI 0 "register_operand" "=r")
2741 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2743 "sethi\\t%%lm(%a1), %0"
2744 [(set_attr "type" "move")
2745 (set_attr "length" "1")])
2747 (define_insn "sethm"
2748 [(set (match_operand:DI 0 "register_operand" "=r")
2749 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2750 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2752 "or\\t%1, %%hm(%a2), %0"
2753 [(set_attr "type" "ialu")
2754 (set_attr "length" "1")])
2756 (define_insn "setlo"
2757 [(set (match_operand:DI 0 "register_operand" "=r")
2758 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2759 (match_operand:DI 2 "symbolic_operand" "")))]
2761 "or\\t%1, %%lo(%a2), %0"
2762 [(set_attr "type" "ialu")
2763 (set_attr "length" "1")])
2765 (define_insn "embmedany_sethi"
2766 [(set (match_operand:DI 0 "register_operand" "=r")
2767 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2768 "TARGET_CM_EMBMEDANY && check_pic (1)"
2769 "sethi\\t%%hi(%a1), %0"
2770 [(set_attr "type" "move")
2771 (set_attr "length" "1")])
2773 (define_insn "embmedany_losum"
2774 [(set (match_operand:DI 0 "register_operand" "=r")
2775 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2776 (match_operand:DI 2 "data_segment_operand" "")))]
2777 "TARGET_CM_EMBMEDANY"
2778 "add\\t%1, %%lo(%a2), %0"
2779 [(set_attr "type" "ialu")
2780 (set_attr "length" "1")])
2782 (define_insn "embmedany_brsum"
2783 [(set (match_operand:DI 0 "register_operand" "=r")
2784 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2785 "TARGET_CM_EMBMEDANY"
2787 [(set_attr "length" "1")])
2789 (define_insn "embmedany_textuhi"
2790 [(set (match_operand:DI 0 "register_operand" "=r")
2791 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2792 "TARGET_CM_EMBMEDANY && check_pic (1)"
2793 "sethi\\t%%uhi(%a1), %0"
2794 [(set_attr "type" "move")
2795 (set_attr "length" "1")])
2797 (define_insn "embmedany_texthi"
2798 [(set (match_operand:DI 0 "register_operand" "=r")
2799 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2800 "TARGET_CM_EMBMEDANY && check_pic (1)"
2801 "sethi\\t%%hi(%a1), %0"
2802 [(set_attr "type" "move")
2803 (set_attr "length" "1")])
2805 (define_insn "embmedany_textulo"
2806 [(set (match_operand:DI 0 "register_operand" "=r")
2807 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2808 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2809 "TARGET_CM_EMBMEDANY"
2810 "or\\t%1, %%ulo(%a2), %0"
2811 [(set_attr "type" "ialu")
2812 (set_attr "length" "1")])
2814 (define_insn "embmedany_textlo"
2815 [(set (match_operand:DI 0 "register_operand" "=r")
2816 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2817 (match_operand:DI 2 "text_segment_operand" "")))]
2818 "TARGET_CM_EMBMEDANY"
2819 "or\\t%1, %%lo(%a2), %0"
2820 [(set_attr "type" "ialu")
2821 (set_attr "length" "1")])
2823 ;; Now some patterns to help reload out a bit.
2824 (define_expand "reload_indi"
2825 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2826 (match_operand:DI 1 "immediate_operand" "")
2827 (match_operand:TI 2 "register_operand" "=&r")])]
2829 || TARGET_CM_EMBMEDANY)
2833 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2834 gen_rtx_REG (DImode, REGNO (operands[2])));
2838 (define_expand "reload_outdi"
2839 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2840 (match_operand:DI 1 "immediate_operand" "")
2841 (match_operand:TI 2 "register_operand" "=&r")])]
2843 || TARGET_CM_EMBMEDANY)
2847 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2848 gen_rtx_REG (DImode, REGNO (operands[2])));
2852 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2854 [(set (match_operand:DI 0 "register_operand" "")
2855 (match_operand:DI 1 "const_int_operand" ""))]
2856 "! TARGET_ARCH64 && reload_completed"
2857 [(clobber (const_int 0))]
2860 #if HOST_BITS_PER_WIDE_INT == 32
2861 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2862 (INTVAL (operands[1]) < 0) ?
2865 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2868 unsigned int low, high;
2870 low = INTVAL (operands[1]) & 0xffffffff;
2871 high = (INTVAL (operands[1]) >> 32) & 0xffffffff;
2872 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2874 /* Slick... but this trick loses if this subreg constant part
2875 can be done in one insn. */
2876 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2877 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2878 gen_highpart (SImode, operands[0])));
2880 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2886 [(set (match_operand:DI 0 "register_operand" "")
2887 (match_operand:DI 1 "const_double_operand" ""))]
2888 "! TARGET_ARCH64 && reload_completed"
2889 [(clobber (const_int 0))]
2892 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2893 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2895 /* Slick... but this trick loses if this subreg constant part
2896 can be done in one insn. */
2897 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2898 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2899 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2901 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2902 gen_highpart (SImode, operands[0])));
2906 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2907 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2913 [(set (match_operand:DI 0 "register_operand" "")
2914 (match_operand:DI 1 "register_operand" ""))]
2915 "! TARGET_ARCH64 && reload_completed"
2916 [(clobber (const_int 0))]
2919 rtx set_dest = operands[0];
2920 rtx set_src = operands[1];
2924 if (GET_CODE (set_dest) == SUBREG)
2925 set_dest = alter_subreg (set_dest);
2926 if (GET_CODE (set_src) == SUBREG)
2927 set_src = alter_subreg (set_src);
2929 dest1 = gen_highpart (SImode, set_dest);
2930 dest2 = gen_lowpart (SImode, set_dest);
2931 src1 = gen_highpart (SImode, set_src);
2932 src2 = gen_lowpart (SImode, set_src);
2934 /* Now emit using the real source and destination we found, swapping
2935 the order if we detect overlap. */
2936 if (reg_overlap_mentioned_p (dest1, src2))
2938 emit_insn (gen_movsi (dest2, src2));
2939 emit_insn (gen_movsi (dest1, src1));
2943 emit_insn (gen_movsi (dest1, src1));
2944 emit_insn (gen_movsi (dest2, src2));
2949 ;; Now handle the cases of memory moves from/to non-even
2950 ;; DI mode register pairs.
2952 [(set (match_operand:DI 0 "register_operand" "")
2953 (match_operand:DI 1 "memory_operand" ""))]
2956 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2957 [(clobber (const_int 0))]
2960 rtx word0 = change_address (operands[1], SImode, NULL_RTX);
2961 rtx word1 = change_address (operands[1], SImode,
2962 plus_constant_for_output (XEXP (word0, 0), 4));
2963 rtx high_part = gen_highpart (SImode, operands[0]);
2964 rtx low_part = gen_lowpart (SImode, operands[0]);
2966 if (reg_overlap_mentioned_p (high_part, word1))
2968 emit_insn (gen_movsi (low_part, word1));
2969 emit_insn (gen_movsi (high_part, word0));
2973 emit_insn (gen_movsi (high_part, word0));
2974 emit_insn (gen_movsi (low_part, word1));
2980 [(set (match_operand:DI 0 "memory_operand" "")
2981 (match_operand:DI 1 "register_operand" ""))]
2984 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2985 [(clobber (const_int 0))]
2988 rtx word0 = change_address (operands[0], SImode, NULL_RTX);
2989 rtx word1 = change_address (operands[0], SImode,
2990 plus_constant_for_output (XEXP (word0, 0), 4));
2991 rtx high_part = gen_highpart (SImode, operands[1]);
2992 rtx low_part = gen_lowpart (SImode, operands[1]);
2994 emit_insn (gen_movsi (word0, high_part));
2995 emit_insn (gen_movsi (word1, low_part));
3000 ;; Floating point move insns
3002 (define_insn "*movsf_insn_novis"
3003 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
3004 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
3005 "(TARGET_FPU && ! TARGET_VIS)
3006 && (register_operand (operands[0], SFmode)
3007 || register_operand (operands[1], SFmode)
3008 || fp_zero_operand (operands[1], SFmode))"
3011 if (GET_CODE (operands[1]) == CONST_DOUBLE
3012 && (which_alternative == 2
3013 || which_alternative == 3
3014 || which_alternative == 4))
3019 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3020 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3021 operands[1] = GEN_INT (i);
3024 switch (which_alternative)
3027 return \"fmovs\\t%1, %0\";
3029 return \"clr\\t%0\";
3031 return \"sethi\\t%%hi(%a1), %0\";
3033 return \"mov\\t%1, %0\";
3038 return \"ld\\t%1, %0\";
3041 return \"st\\t%r1, %0\";
3046 [(set_attr "type" "fpmove,move,move,move,*,load,fpload,fpstore,store")
3047 (set_attr "length" "1")])
3049 (define_insn "*movsf_insn_vis"
3050 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
3051 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
3052 "(TARGET_FPU && TARGET_VIS)
3053 && (register_operand (operands[0], SFmode)
3054 || register_operand (operands[1], SFmode)
3055 || fp_zero_operand (operands[1], SFmode))"
3058 if (GET_CODE (operands[1]) == CONST_DOUBLE
3059 && (which_alternative == 3
3060 || which_alternative == 4
3061 || which_alternative == 5))
3066 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3067 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3068 operands[1] = GEN_INT (i);
3071 switch (which_alternative)
3074 return \"fmovs\\t%1, %0\";
3076 return \"fzeros\\t%0\";
3078 return \"clr\\t%0\";
3080 return \"sethi\\t%%hi(%a1), %0\";
3082 return \"mov\\t%1, %0\";
3087 return \"ld\\t%1, %0\";
3090 return \"st\\t%r1, %0\";
3095 [(set_attr "type" "fpmove,fpmove,move,move,move,*,load,fpload,fpstore,store")
3096 (set_attr "length" "1")])
3098 (define_insn "*movsf_lo_sum"
3099 [(set (match_operand:SF 0 "register_operand" "")
3100 (lo_sum:SF (match_operand:SF 1 "register_operand" "")
3101 (match_operand:SF 2 "const_double_operand" "")))]
3102 "TARGET_FPU && fp_high_losum_p (operands[2])"
3108 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3109 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3110 operands[2] = GEN_INT (i);
3111 return \"or\\t%1, %%lo(%a2), %0\";
3113 [(set_attr "type" "ialu")
3114 (set_attr "length" "1")])
3116 (define_insn "*movsf_high"
3117 [(set (match_operand:SF 0 "register_operand" "")
3118 (high:SF (match_operand:SF 1 "const_double_operand" "")))]
3119 "TARGET_FPU && fp_high_losum_p (operands[1])"
3125 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3126 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3127 operands[1] = GEN_INT (i);
3128 return \"sethi\\t%%hi(%1), %0\";
3130 [(set_attr "type" "move")
3131 (set_attr "length" "1")])
3134 [(set (match_operand:SF 0 "register_operand" "")
3135 (match_operand:SF 1 "const_double_operand" ""))]
3137 && fp_high_losum_p (operands[1])
3138 && (GET_CODE (operands[0]) == REG
3139 && REGNO (operands[0]) < 32)"
3140 [(set (match_dup 0) (high:SF (match_dup 1)))
3141 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3143 ;; Exactly the same as above, except that all `f' cases are deleted.
3144 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3147 (define_insn "*movsf_no_f_insn"
3148 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
3149 (match_operand:SF 1 "input_operand" "r,m,r"))]
3151 && (register_operand (operands[0], SFmode)
3152 || register_operand (operands[1], SFmode))"
3157 [(set_attr "type" "move,load,store")
3158 (set_attr "length" "1")])
3160 (define_expand "movsf"
3161 [(set (match_operand:SF 0 "general_operand" "")
3162 (match_operand:SF 1 "general_operand" ""))]
3166 /* Force SFmode constants into memory. */
3167 if (GET_CODE (operands[0]) == REG
3168 && CONSTANT_P (operands[1]))
3170 /* emit_group_store will send such bogosity to us when it is
3171 not storing directly into memory. So fix this up to avoid
3172 crashes in output_constant_pool. */
3173 if (operands [1] == const0_rtx)
3174 operands[1] = CONST0_RTX (SFmode);
3176 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3179 /* We are able to build any SF constant in integer registers
3180 with at most 2 instructions. */
3181 if (REGNO (operands[0]) < 32)
3184 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3188 /* Handle sets of MEM first. */
3189 if (GET_CODE (operands[0]) == MEM)
3191 if (register_operand (operands[1], SFmode)
3192 || fp_zero_operand (operands[1], SFmode))
3195 if (! reload_in_progress)
3197 operands[0] = validize_mem (operands[0]);
3198 operands[1] = force_reg (SFmode, operands[1]);
3202 /* Fixup PIC cases. */
3205 if (CONSTANT_P (operands[1])
3206 && pic_address_needs_scratch (operands[1]))
3207 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3209 if (symbolic_operand (operands[1], SFmode))
3211 operands[1] = legitimize_pic_address (operands[1],
3213 (reload_in_progress ?
3223 (define_expand "movdf"
3224 [(set (match_operand:DF 0 "general_operand" "")
3225 (match_operand:DF 1 "general_operand" ""))]
3229 /* Force DFmode constants into memory. */
3230 if (GET_CODE (operands[0]) == REG
3231 && CONSTANT_P (operands[1]))
3233 /* emit_group_store will send such bogosity to us when it is
3234 not storing directly into memory. So fix this up to avoid
3235 crashes in output_constant_pool. */
3236 if (operands [1] == const0_rtx)
3237 operands[1] = CONST0_RTX (DFmode);
3239 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3240 && fp_zero_operand (operands[1], DFmode))
3243 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3247 /* Handle MEM cases first. */
3248 if (GET_CODE (operands[0]) == MEM)
3250 if (register_operand (operands[1], DFmode)
3251 || fp_zero_operand (operands[1], DFmode))
3254 if (! reload_in_progress)
3256 operands[0] = validize_mem (operands[0]);
3257 operands[1] = force_reg (DFmode, operands[1]);
3261 /* Fixup PIC cases. */
3264 if (CONSTANT_P (operands[1])
3265 && pic_address_needs_scratch (operands[1]))
3266 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3268 if (symbolic_operand (operands[1], DFmode))
3270 operands[1] = legitimize_pic_address (operands[1],
3272 (reload_in_progress ?
3282 ;; Be careful, fmovd does not exist when !v9.
3283 (define_insn "*movdf_insn_sp32"
3284 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3285 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3288 && (register_operand (operands[0], DFmode)
3289 || register_operand (operands[1], DFmode)
3290 || fp_zero_operand (operands[1], DFmode))"
3302 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3303 (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
3305 (define_insn "*movdf_no_e_insn_sp32"
3306 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3307 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3311 && (register_operand (operands[0], DFmode)
3312 || register_operand (operands[1], DFmode)
3313 || fp_zero_operand (operands[1], DFmode))"
3320 [(set_attr "type" "load,store,*,*,*")
3321 (set_attr "length" "1,1,2,2,2")])
3323 (define_insn "*movdf_no_e_insn_v9_sp32"
3324 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3325 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3329 && (register_operand (operands[0], DFmode)
3330 || register_operand (operands[1], DFmode)
3331 || fp_zero_operand (operands[1], DFmode))"
3338 [(set_attr "type" "load,store,store,*,*")
3339 (set_attr "length" "1,1,1,2,2")])
3341 ;; We have available v9 double floats but not 64-bit
3342 ;; integer registers and no VIS.
3343 (define_insn "*movdf_insn_v9only_novis"
3344 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3345 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3350 && (register_operand (operands[0], DFmode)
3351 || register_operand (operands[1], DFmode)
3352 || fp_zero_operand (operands[1], DFmode))"
3363 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3364 (set_attr "length" "1,1,1,1,1,1,2,2,2")])
3366 ;; We have available v9 double floats but not 64-bit
3367 ;; integer registers but we have VIS.
3368 (define_insn "*movdf_insn_v9only_vis"
3369 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3370 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3374 && (register_operand (operands[0], DFmode)
3375 || register_operand (operands[1], DFmode)
3376 || fp_zero_operand (operands[1], DFmode))"
3388 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3389 (set_attr "length" "1,1,1,1,1,1,1,2,2,2")])
3391 ;; We have available both v9 double floats and 64-bit
3392 ;; integer registers. No VIS though.
3393 (define_insn "*movdf_insn_sp64_novis"
3394 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3395 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3399 && (register_operand (operands[0], DFmode)
3400 || register_operand (operands[1], DFmode)
3401 || fp_zero_operand (operands[1], DFmode))"
3410 [(set_attr "type" "fpmove,load,store,move,load,store,*")
3411 (set_attr "length" "1,1,1,1,1,1,2")])
3413 ;; We have available both v9 double floats and 64-bit
3414 ;; integer registers. And we have VIS.
3415 (define_insn "*movdf_insn_sp64_vis"
3416 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3417 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3421 && (register_operand (operands[0], DFmode)
3422 || register_operand (operands[1], DFmode)
3423 || fp_zero_operand (operands[1], DFmode))"
3433 [(set_attr "type" "fpmove,fpmove,load,store,move,load,store,*")
3434 (set_attr "length" "1,1,1,1,1,1,1,2")])
3436 (define_insn "*movdf_no_e_insn_sp64"
3437 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3438 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3441 && (register_operand (operands[0], DFmode)
3442 || register_operand (operands[1], DFmode)
3443 || fp_zero_operand (operands[1], DFmode))"
3448 [(set_attr "type" "move,load,store")
3449 (set_attr "length" "1")])
3452 [(set (match_operand:DF 0 "register_operand" "")
3453 (match_operand:DF 1 "const_double_operand" ""))]
3455 && (GET_CODE (operands[0]) == REG
3456 && REGNO (operands[0]) < 32)
3457 && ! fp_zero_operand(operands[1], DFmode)
3458 && reload_completed"
3459 [(clobber (const_int 0))]
3465 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3466 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3467 if (GET_CODE (operands[0]) == SUBREG)
3468 operands[0] = alter_subreg (operands[0]);
3469 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3473 #if HOST_BITS_PER_WIDE_INT == 64
3476 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3477 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3478 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3480 emit_insn (gen_movdi (operands[0],
3481 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
3487 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3490 /* Slick... but this trick loses if this subreg constant part
3491 can be done in one insn. */
3493 && !(SPARC_SETHI_P (l[0])
3494 || SPARC_SIMM13_P (l[0])))
3496 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3497 gen_highpart (SImode, operands[0])));
3501 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3508 ;; Ok, now the splits to handle all the multi insn and
3509 ;; mis-aligned memory address cases.
3510 ;; In these splits please take note that we must be
3511 ;; careful when V9 but not ARCH64 because the integer
3512 ;; register DFmode cases must be handled.
3514 [(set (match_operand:DF 0 "register_operand" "")
3515 (match_operand:DF 1 "register_operand" ""))]
3518 && ((GET_CODE (operands[0]) == REG
3519 && REGNO (operands[0]) < 32)
3520 || (GET_CODE (operands[0]) == SUBREG
3521 && GET_CODE (SUBREG_REG (operands[0])) == REG
3522 && REGNO (SUBREG_REG (operands[0])) < 32))))
3523 && reload_completed"
3524 [(clobber (const_int 0))]
3527 rtx set_dest = operands[0];
3528 rtx set_src = operands[1];
3532 if (GET_CODE (set_dest) == SUBREG)
3533 set_dest = alter_subreg (set_dest);
3534 if (GET_CODE (set_src) == SUBREG)
3535 set_src = alter_subreg (set_src);
3537 dest1 = gen_highpart (SFmode, set_dest);
3538 dest2 = gen_lowpart (SFmode, set_dest);
3539 src1 = gen_highpart (SFmode, set_src);
3540 src2 = gen_lowpart (SFmode, set_src);
3542 /* Now emit using the real source and destination we found, swapping
3543 the order if we detect overlap. */
3544 if (reg_overlap_mentioned_p (dest1, src2))
3546 emit_insn (gen_movsf (dest2, src2));
3547 emit_insn (gen_movsf (dest1, src1));
3551 emit_insn (gen_movsf (dest1, src1));
3552 emit_insn (gen_movsf (dest2, src2));
3558 [(set (match_operand:DF 0 "register_operand" "")
3559 (match_operand:DF 1 "memory_operand" ""))]
3562 && (((REGNO (operands[0]) % 2) != 0)
3563 || ! mem_min_alignment (operands[1], 8))
3564 && offsettable_memref_p (operands[1])"
3565 [(clobber (const_int 0))]
3568 rtx word0 = change_address (operands[1], SFmode, NULL_RTX);
3569 rtx word1 = change_address (operands[1], SFmode,
3570 plus_constant_for_output (XEXP (word0, 0), 4));
3572 if (GET_CODE (operands[0]) == SUBREG)
3573 operands[0] = alter_subreg (operands[0]);
3575 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3577 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3579 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3584 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3586 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3593 [(set (match_operand:DF 0 "memory_operand" "")
3594 (match_operand:DF 1 "register_operand" ""))]
3597 && (((REGNO (operands[1]) % 2) != 0)
3598 || ! mem_min_alignment (operands[0], 8))
3599 && offsettable_memref_p (operands[0])"
3600 [(clobber (const_int 0))]
3603 rtx word0 = change_address (operands[0], SFmode, NULL_RTX);
3604 rtx word1 = change_address (operands[0], SFmode,
3605 plus_constant_for_output (XEXP (word0, 0), 4));
3607 if (GET_CODE (operands[1]) == SUBREG)
3608 operands[1] = alter_subreg (operands[1]);
3609 emit_insn (gen_movsf (word0,
3610 gen_highpart (SFmode, operands[1])));
3611 emit_insn (gen_movsf (word1,
3612 gen_lowpart (SFmode, operands[1])));
3617 [(set (match_operand:DF 0 "memory_operand" "")
3618 (match_operand:DF 1 "fp_zero_operand" ""))]
3622 && ! mem_min_alignment (operands[0], 8)))
3623 && offsettable_memref_p (operands[0])"
3624 [(clobber (const_int 0))]
3629 dest1 = change_address (operands[0], SFmode, NULL_RTX);
3630 dest2 = change_address (operands[0], SFmode,
3631 plus_constant_for_output (XEXP (dest1, 0), 4));
3632 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3633 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3638 [(set (match_operand:DF 0 "register_operand" "")
3639 (match_operand:DF 1 "fp_zero_operand" ""))]
3642 && ((GET_CODE (operands[0]) == REG
3643 && REGNO (operands[0]) < 32)
3644 || (GET_CODE (operands[0]) == SUBREG
3645 && GET_CODE (SUBREG_REG (operands[0])) == REG
3646 && REGNO (SUBREG_REG (operands[0])) < 32))"
3647 [(clobber (const_int 0))]
3650 rtx set_dest = operands[0];
3653 if (GET_CODE (set_dest) == SUBREG)
3654 set_dest = alter_subreg (set_dest);
3655 dest1 = gen_highpart (SFmode, set_dest);
3656 dest2 = gen_lowpart (SFmode, set_dest);
3657 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3658 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3662 (define_expand "movtf"
3663 [(set (match_operand:TF 0 "general_operand" "")
3664 (match_operand:TF 1 "general_operand" ""))]
3668 /* Force TFmode constants into memory. */
3669 if (GET_CODE (operands[0]) == REG
3670 && CONSTANT_P (operands[1]))
3672 /* emit_group_store will send such bogosity to us when it is
3673 not storing directly into memory. So fix this up to avoid
3674 crashes in output_constant_pool. */
3675 if (operands [1] == const0_rtx)
3676 operands[1] = CONST0_RTX (TFmode);
3678 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3681 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3685 /* Handle MEM cases first, note that only v9 guarentees
3686 full 16-byte alignment for quads. */
3687 if (GET_CODE (operands[0]) == MEM)
3689 if (register_operand (operands[1], TFmode)
3690 || fp_zero_operand (operands[1], TFmode))
3693 if (! reload_in_progress)
3695 operands[0] = validize_mem (operands[0]);
3696 operands[1] = force_reg (TFmode, operands[1]);
3700 /* Fixup PIC cases. */
3703 if (CONSTANT_P (operands[1])
3704 && pic_address_needs_scratch (operands[1]))
3705 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3707 if (symbolic_operand (operands[1], TFmode))
3709 operands[1] = legitimize_pic_address (operands[1],
3711 (reload_in_progress ?
3721 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3722 ;; we must split them all. :-(
3723 (define_insn "*movtf_insn_sp32"
3724 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3725 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3729 && (register_operand (operands[0], TFmode)
3730 || register_operand (operands[1], TFmode)
3731 || fp_zero_operand (operands[1], TFmode))"
3733 [(set_attr "length" "4")])
3735 (define_insn "*movtf_insn_vis_sp32"
3736 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3737 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3741 && (register_operand (operands[0], TFmode)
3742 || register_operand (operands[1], TFmode)
3743 || fp_zero_operand (operands[1], TFmode))"
3745 [(set_attr "length" "4")])
3747 ;; Exactly the same as above, except that all `e' cases are deleted.
3748 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3751 (define_insn "*movtf_no_e_insn_sp32"
3752 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3753 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3756 && (register_operand (operands[0], TFmode)
3757 || register_operand (operands[1], TFmode)
3758 || fp_zero_operand (operands[1], TFmode))"
3760 [(set_attr "length" "4")])
3762 ;; Now handle the float reg cases directly when arch64,
3763 ;; hard_quad, and proper reg number alignment are all true.
3764 (define_insn "*movtf_insn_hq_sp64"
3765 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3766 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3771 && (register_operand (operands[0], TFmode)
3772 || register_operand (operands[1], TFmode)
3773 || fp_zero_operand (operands[1], TFmode))"
3780 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3781 (set_attr "length" "1,1,1,2,2")])
3783 (define_insn "*movtf_insn_hq_vis_sp64"
3784 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3785 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3790 && (register_operand (operands[0], TFmode)
3791 || register_operand (operands[1], TFmode)
3792 || fp_zero_operand (operands[1], TFmode))"
3800 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3801 (set_attr "length" "1,1,1,2,2,2")])
3803 ;; Now we allow the integer register cases even when
3804 ;; only arch64 is true.
3805 (define_insn "*movtf_insn_sp64"
3806 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3807 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3811 && ! TARGET_HARD_QUAD
3812 && (register_operand (operands[0], TFmode)
3813 || register_operand (operands[1], TFmode)
3814 || fp_zero_operand (operands[1], TFmode))"
3816 [(set_attr "length" "2")])
3818 (define_insn "*movtf_insn_vis_sp64"
3819 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3820 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3824 && ! TARGET_HARD_QUAD
3825 && (register_operand (operands[0], TFmode)
3826 || register_operand (operands[1], TFmode)
3827 || fp_zero_operand (operands[1], TFmode))"
3829 [(set_attr "length" "2")])
3831 (define_insn "*movtf_no_e_insn_sp64"
3832 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3833 (match_operand:TF 1 "input_operand" "orG,rG"))]
3836 && (register_operand (operands[0], TFmode)
3837 || register_operand (operands[1], TFmode)
3838 || fp_zero_operand (operands[1], TFmode))"
3840 [(set_attr "length" "2")])
3842 ;; Now all the splits to handle multi-insn TF mode moves.
3844 [(set (match_operand:TF 0 "register_operand" "")
3845 (match_operand:TF 1 "register_operand" ""))]
3849 && ! TARGET_HARD_QUAD))"
3850 [(clobber (const_int 0))]
3853 rtx set_dest = operands[0];
3854 rtx set_src = operands[1];
3858 if (GET_CODE (set_dest) == SUBREG)
3859 set_dest = alter_subreg (set_dest);
3860 if (GET_CODE (set_src) == SUBREG)
3861 set_src = alter_subreg (set_src);
3863 dest1 = gen_df_reg (set_dest, 0);
3864 dest2 = gen_df_reg (set_dest, 1);
3865 src1 = gen_df_reg (set_src, 0);
3866 src2 = gen_df_reg (set_src, 1);
3868 /* Now emit using the real source and destination we found, swapping
3869 the order if we detect overlap. */
3870 if (reg_overlap_mentioned_p (dest1, src2))
3872 emit_insn (gen_movdf (dest2, src2));
3873 emit_insn (gen_movdf (dest1, src1));
3877 emit_insn (gen_movdf (dest1, src1));
3878 emit_insn (gen_movdf (dest2, src2));
3884 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3885 (match_operand:TF 1 "fp_zero_operand" ""))]
3887 [(clobber (const_int 0))]
3890 rtx set_dest = operands[0];
3893 switch (GET_CODE (set_dest))
3896 set_dest = alter_subreg (set_dest);
3899 dest1 = gen_df_reg (set_dest, 0);
3900 dest2 = gen_df_reg (set_dest, 1);
3903 dest1 = change_address (set_dest, DFmode, NULL_RTX);
3904 dest2 = change_address (set_dest, DFmode,
3905 plus_constant_for_output (XEXP (dest1, 0), 8));
3911 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3912 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3917 [(set (match_operand:TF 0 "register_operand" "")
3918 (match_operand:TF 1 "memory_operand" ""))]
3920 && offsettable_memref_p (operands[1]))"
3921 [(clobber (const_int 0))]
3924 rtx word0 = change_address (operands[1], DFmode, NULL_RTX);
3925 rtx word1 = change_address (operands[1], DFmode,
3926 plus_constant_for_output (XEXP (word0, 0), 8));
3927 rtx set_dest, dest1, dest2;
3929 set_dest = operands[0];
3930 if (GET_CODE (set_dest) == SUBREG)
3931 set_dest = alter_subreg (set_dest);
3933 dest1 = gen_df_reg (set_dest, 0);
3934 dest2 = gen_df_reg (set_dest, 1);
3936 /* Now output, ordering such that we don't clobber any registers
3937 mentioned in the address. */
3938 if (reg_overlap_mentioned_p (dest1, word1))
3941 emit_insn (gen_movdf (dest2, word1));
3942 emit_insn (gen_movdf (dest1, word0));
3946 emit_insn (gen_movdf (dest1, word0));
3947 emit_insn (gen_movdf (dest2, word1));
3953 [(set (match_operand:TF 0 "memory_operand" "")
3954 (match_operand:TF 1 "register_operand" ""))]
3956 && offsettable_memref_p (operands[0]))"
3957 [(clobber (const_int 0))]
3960 rtx word1 = change_address (operands[0], DFmode, NULL_RTX);
3961 rtx word2 = change_address (operands[0], DFmode,
3962 plus_constant_for_output (XEXP (word1, 0), 8));
3965 set_src = operands[1];
3966 if (GET_CODE (set_src) == SUBREG)
3967 set_src = alter_subreg (set_src);
3969 emit_insn (gen_movdf (word1, gen_df_reg (set_src, 0)));
3970 emit_insn (gen_movdf (word2, gen_df_reg (set_src, 1)));
3974 ;; Sparc V9 conditional move instructions.
3976 ;; We can handle larger constants here for some flavors, but for now we keep
3977 ;; it simple and only allow those constants supported by all flavours.
3978 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3979 ;; 3 contains the constant if one is present, but we handle either for
3980 ;; generality (sparc.c puts a constant in operand 2).
3982 (define_expand "movqicc"
3983 [(set (match_operand:QI 0 "register_operand" "")
3984 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3985 (match_operand:QI 2 "arith10_operand" "")
3986 (match_operand:QI 3 "arith10_operand" "")))]
3990 enum rtx_code code = GET_CODE (operands[1]);
3992 if (GET_MODE (sparc_compare_op0) == DImode
3996 if (sparc_compare_op1 == const0_rtx
3997 && GET_CODE (sparc_compare_op0) == REG
3998 && GET_MODE (sparc_compare_op0) == DImode
3999 && v9_regcmp_p (code))
4001 operands[1] = gen_rtx_fmt_ee (code, DImode,
4002 sparc_compare_op0, sparc_compare_op1);
4006 rtx cc_reg = gen_compare_reg (code,
4007 sparc_compare_op0, sparc_compare_op1);
4008 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4012 (define_expand "movhicc"
4013 [(set (match_operand:HI 0 "register_operand" "")
4014 (if_then_else:HI (match_operand 1 "comparison_operator" "")
4015 (match_operand:HI 2 "arith10_operand" "")
4016 (match_operand:HI 3 "arith10_operand" "")))]
4020 enum rtx_code code = GET_CODE (operands[1]);
4022 if (GET_MODE (sparc_compare_op0) == DImode
4026 if (sparc_compare_op1 == const0_rtx
4027 && GET_CODE (sparc_compare_op0) == REG
4028 && GET_MODE (sparc_compare_op0) == DImode
4029 && v9_regcmp_p (code))
4031 operands[1] = gen_rtx_fmt_ee (code, DImode,
4032 sparc_compare_op0, sparc_compare_op1);
4036 rtx cc_reg = gen_compare_reg (code,
4037 sparc_compare_op0, sparc_compare_op1);
4038 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4042 (define_expand "movsicc"
4043 [(set (match_operand:SI 0 "register_operand" "")
4044 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4045 (match_operand:SI 2 "arith10_operand" "")
4046 (match_operand:SI 3 "arith10_operand" "")))]
4050 enum rtx_code code = GET_CODE (operands[1]);
4051 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
4053 if (sparc_compare_op1 == const0_rtx
4054 && GET_CODE (sparc_compare_op0) == REG
4055 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
4057 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
4058 sparc_compare_op0, sparc_compare_op1);
4062 rtx cc_reg = gen_compare_reg (code,
4063 sparc_compare_op0, sparc_compare_op1);
4064 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4065 cc_reg, const0_rtx);
4069 (define_expand "movdicc"
4070 [(set (match_operand:DI 0 "register_operand" "")
4071 (if_then_else:DI (match_operand 1 "comparison_operator" "")
4072 (match_operand:DI 2 "arith10_double_operand" "")
4073 (match_operand:DI 3 "arith10_double_operand" "")))]
4077 enum rtx_code code = GET_CODE (operands[1]);
4079 if (sparc_compare_op1 == const0_rtx
4080 && GET_CODE (sparc_compare_op0) == REG
4081 && GET_MODE (sparc_compare_op0) == DImode
4082 && v9_regcmp_p (code))
4084 operands[1] = gen_rtx_fmt_ee (code, DImode,
4085 sparc_compare_op0, sparc_compare_op1);
4089 rtx cc_reg = gen_compare_reg (code,
4090 sparc_compare_op0, sparc_compare_op1);
4091 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4092 cc_reg, const0_rtx);
4096 (define_expand "movsfcc"
4097 [(set (match_operand:SF 0 "register_operand" "")
4098 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4099 (match_operand:SF 2 "register_operand" "")
4100 (match_operand:SF 3 "register_operand" "")))]
4101 "TARGET_V9 && TARGET_FPU"
4104 enum rtx_code code = GET_CODE (operands[1]);
4106 if (GET_MODE (sparc_compare_op0) == DImode
4110 if (sparc_compare_op1 == const0_rtx
4111 && GET_CODE (sparc_compare_op0) == REG
4112 && GET_MODE (sparc_compare_op0) == DImode
4113 && v9_regcmp_p (code))
4115 operands[1] = gen_rtx_fmt_ee (code, DImode,
4116 sparc_compare_op0, sparc_compare_op1);
4120 rtx cc_reg = gen_compare_reg (code,
4121 sparc_compare_op0, sparc_compare_op1);
4122 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4126 (define_expand "movdfcc"
4127 [(set (match_operand:DF 0 "register_operand" "")
4128 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4129 (match_operand:DF 2 "register_operand" "")
4130 (match_operand:DF 3 "register_operand" "")))]
4131 "TARGET_V9 && TARGET_FPU"
4134 enum rtx_code code = GET_CODE (operands[1]);
4136 if (GET_MODE (sparc_compare_op0) == DImode
4140 if (sparc_compare_op1 == const0_rtx
4141 && GET_CODE (sparc_compare_op0) == REG
4142 && GET_MODE (sparc_compare_op0) == DImode
4143 && v9_regcmp_p (code))
4145 operands[1] = gen_rtx_fmt_ee (code, DImode,
4146 sparc_compare_op0, sparc_compare_op1);
4150 rtx cc_reg = gen_compare_reg (code,
4151 sparc_compare_op0, sparc_compare_op1);
4152 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4156 (define_expand "movtfcc"
4157 [(set (match_operand:TF 0 "register_operand" "")
4158 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4159 (match_operand:TF 2 "register_operand" "")
4160 (match_operand:TF 3 "register_operand" "")))]
4161 "TARGET_V9 && TARGET_FPU"
4164 enum rtx_code code = GET_CODE (operands[1]);
4166 if (GET_MODE (sparc_compare_op0) == DImode
4170 if (sparc_compare_op1 == const0_rtx
4171 && GET_CODE (sparc_compare_op0) == REG
4172 && GET_MODE (sparc_compare_op0) == DImode
4173 && v9_regcmp_p (code))
4175 operands[1] = gen_rtx_fmt_ee (code, DImode,
4176 sparc_compare_op0, sparc_compare_op1);
4180 rtx cc_reg = gen_compare_reg (code,
4181 sparc_compare_op0, sparc_compare_op1);
4182 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4186 ;; Conditional move define_insns.
4188 (define_insn "*movqi_cc_sp64"
4189 [(set (match_operand:QI 0 "register_operand" "=r,r")
4190 (if_then_else:QI (match_operator 1 "comparison_operator"
4191 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4193 (match_operand:QI 3 "arith11_operand" "rL,0")
4194 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4197 mov%C1\\t%x2, %3, %0
4198 mov%c1\\t%x2, %4, %0"
4199 [(set_attr "type" "cmove")
4200 (set_attr "length" "1")])
4202 (define_insn "*movhi_cc_sp64"
4203 [(set (match_operand:HI 0 "register_operand" "=r,r")
4204 (if_then_else:HI (match_operator 1 "comparison_operator"
4205 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4207 (match_operand:HI 3 "arith11_operand" "rL,0")
4208 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4211 mov%C1\\t%x2, %3, %0
4212 mov%c1\\t%x2, %4, %0"
4213 [(set_attr "type" "cmove")
4214 (set_attr "length" "1")])
4216 (define_insn "*movsi_cc_sp64"
4217 [(set (match_operand:SI 0 "register_operand" "=r,r")
4218 (if_then_else:SI (match_operator 1 "comparison_operator"
4219 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4221 (match_operand:SI 3 "arith11_operand" "rL,0")
4222 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4225 mov%C1\\t%x2, %3, %0
4226 mov%c1\\t%x2, %4, %0"
4227 [(set_attr "type" "cmove")
4228 (set_attr "length" "1")])
4230 ;; ??? The constraints of operands 3,4 need work.
4231 (define_insn "*movdi_cc_sp64"
4232 [(set (match_operand:DI 0 "register_operand" "=r,r")
4233 (if_then_else:DI (match_operator 1 "comparison_operator"
4234 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4236 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4237 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4240 mov%C1\\t%x2, %3, %0
4241 mov%c1\\t%x2, %4, %0"
4242 [(set_attr "type" "cmove")
4243 (set_attr "length" "1")])
4245 (define_insn "*movdi_cc_sp64_trunc"
4246 [(set (match_operand:SI 0 "register_operand" "=r,r")
4247 (if_then_else:SI (match_operator 1 "comparison_operator"
4248 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4250 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4251 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4254 mov%C1\\t%x2, %3, %0
4255 mov%c1\\t%x2, %4, %0"
4256 [(set_attr "type" "cmove")
4257 (set_attr "length" "1")])
4259 (define_insn "*movsf_cc_sp64"
4260 [(set (match_operand:SF 0 "register_operand" "=f,f")
4261 (if_then_else:SF (match_operator 1 "comparison_operator"
4262 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4264 (match_operand:SF 3 "register_operand" "f,0")
4265 (match_operand:SF 4 "register_operand" "0,f")))]
4266 "TARGET_V9 && TARGET_FPU"
4268 fmovs%C1\\t%x2, %3, %0
4269 fmovs%c1\\t%x2, %4, %0"
4270 [(set_attr "type" "fpcmove")
4271 (set_attr "length" "1")])
4273 (define_insn "movdf_cc_sp64"
4274 [(set (match_operand:DF 0 "register_operand" "=e,e")
4275 (if_then_else:DF (match_operator 1 "comparison_operator"
4276 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4278 (match_operand:DF 3 "register_operand" "e,0")
4279 (match_operand:DF 4 "register_operand" "0,e")))]
4280 "TARGET_V9 && TARGET_FPU"
4282 fmovd%C1\\t%x2, %3, %0
4283 fmovd%c1\\t%x2, %4, %0"
4284 [(set_attr "type" "fpcmove")
4285 (set_attr "length" "1")])
4287 (define_insn "*movtf_cc_hq_sp64"
4288 [(set (match_operand:TF 0 "register_operand" "=e,e")
4289 (if_then_else:TF (match_operator 1 "comparison_operator"
4290 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4292 (match_operand:TF 3 "register_operand" "e,0")
4293 (match_operand:TF 4 "register_operand" "0,e")))]
4294 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4296 fmovq%C1\\t%x2, %3, %0
4297 fmovq%c1\\t%x2, %4, %0"
4298 [(set_attr "type" "fpcmove")
4299 (set_attr "length" "1")])
4301 (define_insn "*movtf_cc_sp64"
4302 [(set (match_operand:TF 0 "register_operand" "=e,e")
4303 (if_then_else:TF (match_operator 1 "comparison_operator"
4304 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4306 (match_operand:TF 3 "register_operand" "e,0")
4307 (match_operand:TF 4 "register_operand" "0,e")))]
4308 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4310 [(set_attr "type" "fpcmove")
4311 (set_attr "length" "2")])
4314 [(set (match_operand:TF 0 "register_operand" "=e,e")
4315 (if_then_else:TF (match_operator 1 "comparison_operator"
4316 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4318 (match_operand:TF 3 "register_operand" "e,0")
4319 (match_operand:TF 4 "register_operand" "0,e")))]
4320 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4321 [(clobber (const_int 0))]
4324 rtx set_dest = operands[0];
4325 rtx set_srca = operands[3];
4326 rtx set_srcb = operands[4];
4327 int third = rtx_equal_p (set_dest, set_srca);
4329 rtx srca1, srca2, srcb1, srcb2;
4331 if (GET_CODE (set_dest) == SUBREG)
4332 set_dest = alter_subreg (set_dest);
4333 if (GET_CODE (set_srca) == SUBREG)
4334 set_srca = alter_subreg (set_srca);
4335 if (GET_CODE (set_srcb) == SUBREG)
4336 set_srcb = alter_subreg (set_srcb);
4338 dest1 = gen_df_reg (set_dest, 0);
4339 dest2 = gen_df_reg (set_dest, 1);
4340 srca1 = gen_df_reg (set_srca, 0);
4341 srca2 = gen_df_reg (set_srca, 1);
4342 srcb1 = gen_df_reg (set_srcb, 0);
4343 srcb2 = gen_df_reg (set_srcb, 1);
4345 /* Now emit using the real source and destination we found, swapping
4346 the order if we detect overlap. */
4347 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4348 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4350 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4351 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4355 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4356 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4361 (define_insn "*movqi_cc_reg_sp64"
4362 [(set (match_operand:QI 0 "register_operand" "=r,r")
4363 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4364 [(match_operand:DI 2 "register_operand" "r,r")
4366 (match_operand:QI 3 "arith10_operand" "rM,0")
4367 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4370 movr%D1\\t%2, %r3, %0
4371 movr%d1\\t%2, %r4, %0"
4372 [(set_attr "type" "cmove")
4373 (set_attr "length" "1")])
4375 (define_insn "*movhi_cc_reg_sp64"
4376 [(set (match_operand:HI 0 "register_operand" "=r,r")
4377 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4378 [(match_operand:DI 2 "register_operand" "r,r")
4380 (match_operand:HI 3 "arith10_operand" "rM,0")
4381 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4384 movr%D1\\t%2, %r3, %0
4385 movr%d1\\t%2, %r4, %0"
4386 [(set_attr "type" "cmove")
4387 (set_attr "length" "1")])
4389 (define_insn "*movsi_cc_reg_sp64"
4390 [(set (match_operand:SI 0 "register_operand" "=r,r")
4391 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4392 [(match_operand:DI 2 "register_operand" "r,r")
4394 (match_operand:SI 3 "arith10_operand" "rM,0")
4395 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4398 movr%D1\\t%2, %r3, %0
4399 movr%d1\\t%2, %r4, %0"
4400 [(set_attr "type" "cmove")
4401 (set_attr "length" "1")])
4403 ;; ??? The constraints of operands 3,4 need work.
4404 (define_insn "*movdi_cc_reg_sp64"
4405 [(set (match_operand:DI 0 "register_operand" "=r,r")
4406 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4407 [(match_operand:DI 2 "register_operand" "r,r")
4409 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4410 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4413 movr%D1\\t%2, %r3, %0
4414 movr%d1\\t%2, %r4, %0"
4415 [(set_attr "type" "cmove")
4416 (set_attr "length" "1")])
4418 (define_insn "*movdi_cc_reg_sp64_trunc"
4419 [(set (match_operand:SI 0 "register_operand" "=r,r")
4420 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4421 [(match_operand:DI 2 "register_operand" "r,r")
4423 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4424 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4427 movr%D1\\t%2, %r3, %0
4428 movr%d1\\t%2, %r4, %0"
4429 [(set_attr "type" "cmove")
4430 (set_attr "length" "1")])
4432 (define_insn "*movsf_cc_reg_sp64"
4433 [(set (match_operand:SF 0 "register_operand" "=f,f")
4434 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4435 [(match_operand:DI 2 "register_operand" "r,r")
4437 (match_operand:SF 3 "register_operand" "f,0")
4438 (match_operand:SF 4 "register_operand" "0,f")))]
4439 "TARGET_ARCH64 && TARGET_FPU"
4441 fmovrs%D1\\t%2, %3, %0
4442 fmovrs%d1\\t%2, %4, %0"
4443 [(set_attr "type" "fpcmove")
4444 (set_attr "length" "1")])
4446 (define_insn "movdf_cc_reg_sp64"
4447 [(set (match_operand:DF 0 "register_operand" "=e,e")
4448 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4449 [(match_operand:DI 2 "register_operand" "r,r")
4451 (match_operand:DF 3 "register_operand" "e,0")
4452 (match_operand:DF 4 "register_operand" "0,e")))]
4453 "TARGET_ARCH64 && TARGET_FPU"
4455 fmovrd%D1\\t%2, %3, %0
4456 fmovrd%d1\\t%2, %4, %0"
4457 [(set_attr "type" "fpcmove")
4458 (set_attr "length" "1")])
4460 (define_insn "*movtf_cc_reg_hq_sp64"
4461 [(set (match_operand:TF 0 "register_operand" "=e,e")
4462 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4463 [(match_operand:DI 2 "register_operand" "r,r")
4465 (match_operand:TF 3 "register_operand" "e,0")
4466 (match_operand:TF 4 "register_operand" "0,e")))]
4467 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4469 fmovrq%D1\\t%2, %3, %0
4470 fmovrq%d1\\t%2, %4, %0"
4471 [(set_attr "type" "fpcmove")
4472 (set_attr "length" "1")])
4474 (define_insn "*movtf_cc_reg_sp64"
4475 [(set (match_operand:TF 0 "register_operand" "=e,e")
4476 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4477 [(match_operand:DI 2 "register_operand" "r,r")
4479 (match_operand:TF 3 "register_operand" "e,0")
4480 (match_operand:TF 4 "register_operand" "0,e")))]
4481 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4483 [(set_attr "type" "fpcmove")
4484 (set_attr "length" "2")])
4487 [(set (match_operand:TF 0 "register_operand" "=e,e")
4488 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4489 [(match_operand:DI 2 "register_operand" "r,r")
4491 (match_operand:TF 3 "register_operand" "e,0")
4492 (match_operand:TF 4 "register_operand" "0,e")))]
4493 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4494 [(clobber (const_int 0))]
4497 rtx set_dest = operands[0];
4498 rtx set_srca = operands[3];
4499 rtx set_srcb = operands[4];
4500 int third = rtx_equal_p (set_dest, set_srca);
4502 rtx srca1, srca2, srcb1, srcb2;
4504 if (GET_CODE (set_dest) == SUBREG)
4505 set_dest = alter_subreg (set_dest);
4506 if (GET_CODE (set_srca) == SUBREG)
4507 set_srca = alter_subreg (set_srca);
4508 if (GET_CODE (set_srcb) == SUBREG)
4509 set_srcb = alter_subreg (set_srcb);
4511 dest1 = gen_df_reg (set_dest, 0);
4512 dest2 = gen_df_reg (set_dest, 1);
4513 srca1 = gen_df_reg (set_srca, 0);
4514 srca2 = gen_df_reg (set_srca, 1);
4515 srcb1 = gen_df_reg (set_srcb, 0);
4516 srcb2 = gen_df_reg (set_srcb, 1);
4518 /* Now emit using the real source and destination we found, swapping
4519 the order if we detect overlap. */
4520 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4521 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4523 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4524 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4528 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4529 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4535 ;;- zero extension instructions
4537 ;; These patterns originally accepted general_operands, however, slightly
4538 ;; better code is generated by only accepting register_operands, and then
4539 ;; letting combine generate the ldu[hb] insns.
4541 (define_expand "zero_extendhisi2"
4542 [(set (match_operand:SI 0 "register_operand" "")
4543 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4547 rtx temp = gen_reg_rtx (SImode);
4548 rtx shift_16 = GEN_INT (16);
4549 int op1_subword = 0;
4551 if (GET_CODE (operand1) == SUBREG)
4553 op1_subword = SUBREG_WORD (operand1);
4554 operand1 = XEXP (operand1, 0);
4557 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4559 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4563 (define_insn "*zero_extendhisi2_insn"
4564 [(set (match_operand:SI 0 "register_operand" "=r")
4565 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4568 [(set_attr "type" "load")
4569 (set_attr "length" "1")])
4571 (define_expand "zero_extendqihi2"
4572 [(set (match_operand:HI 0 "register_operand" "")
4573 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4577 (define_insn "*zero_extendqihi2_insn"
4578 [(set (match_operand:HI 0 "register_operand" "=r,r")
4579 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4580 "GET_CODE (operands[1]) != CONST_INT"
4584 [(set_attr "type" "unary,load")
4585 (set_attr "length" "1")])
4587 (define_expand "zero_extendqisi2"
4588 [(set (match_operand:SI 0 "register_operand" "")
4589 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4593 (define_insn "*zero_extendqisi2_insn"
4594 [(set (match_operand:SI 0 "register_operand" "=r,r")
4595 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4596 "GET_CODE (operands[1]) != CONST_INT"
4600 [(set_attr "type" "unary,load")
4601 (set_attr "length" "1")])
4603 (define_expand "zero_extendqidi2"
4604 [(set (match_operand:DI 0 "register_operand" "")
4605 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4609 (define_insn "*zero_extendqidi2_insn"
4610 [(set (match_operand:DI 0 "register_operand" "=r,r")
4611 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4612 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4616 [(set_attr "type" "unary,load")
4617 (set_attr "length" "1")])
4619 (define_expand "zero_extendhidi2"
4620 [(set (match_operand:DI 0 "register_operand" "")
4621 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4625 rtx temp = gen_reg_rtx (DImode);
4626 rtx shift_48 = GEN_INT (48);
4627 int op1_subword = 0;
4629 if (GET_CODE (operand1) == SUBREG)
4631 op1_subword = SUBREG_WORD (operand1);
4632 operand1 = XEXP (operand1, 0);
4635 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4637 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4641 (define_insn "*zero_extendhidi2_insn"
4642 [(set (match_operand:DI 0 "register_operand" "=r")
4643 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4646 [(set_attr "type" "load")
4647 (set_attr "length" "1")])
4650 ;; ??? Write truncdisi pattern using sra?
4652 (define_expand "zero_extendsidi2"
4653 [(set (match_operand:DI 0 "register_operand" "")
4654 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4658 (define_insn "*zero_extendsidi2_insn_sp64"
4659 [(set (match_operand:DI 0 "register_operand" "=r,r")
4660 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4661 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4665 [(set_attr "type" "shift,load")
4666 (set_attr "length" "1")])
4668 (define_insn "*zero_extendsidi2_insn_sp32"
4669 [(set (match_operand:DI 0 "register_operand" "=r")
4670 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4673 [(set_attr "type" "unary")
4674 (set_attr "length" "2")])
4677 [(set (match_operand:DI 0 "register_operand" "")
4678 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4679 "! TARGET_ARCH64 && reload_completed"
4680 [(set (match_dup 2) (match_dup 3))
4681 (set (match_dup 4) (match_dup 5))]
4686 if (GET_CODE (operands[0]) == SUBREG)
4687 operands[0] = alter_subreg (operands[0]);
4689 dest1 = gen_highpart (SImode, operands[0]);
4690 dest2 = gen_lowpart (SImode, operands[0]);
4692 /* Swap the order in case of overlap. */
4693 if (REGNO (dest1) == REGNO (operands[1]))
4695 operands[2] = dest2;
4696 operands[3] = operands[1];
4697 operands[4] = dest1;
4698 operands[5] = const0_rtx;
4702 operands[2] = dest1;
4703 operands[3] = const0_rtx;
4704 operands[4] = dest2;
4705 operands[5] = operands[1];
4709 ;; Simplify comparisons of extended values.
4711 (define_insn "*cmp_zero_extendqisi2"
4713 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4716 "andcc\\t%0, 0xff, %%g0"
4717 [(set_attr "type" "compare")
4718 (set_attr "length" "1")])
4720 (define_insn "*cmp_zero_qi"
4722 (compare:CC (match_operand:QI 0 "register_operand" "r")
4725 "andcc\\t%0, 0xff, %%g0"
4726 [(set_attr "type" "compare")
4727 (set_attr "length" "1")])
4729 (define_insn "*cmp_zero_extendqisi2_set"
4731 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4733 (set (match_operand:SI 0 "register_operand" "=r")
4734 (zero_extend:SI (match_dup 1)))]
4736 "andcc\\t%1, 0xff, %0"
4737 [(set_attr "type" "compare")
4738 (set_attr "length" "1")])
4740 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4742 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4745 (set (match_operand:SI 0 "register_operand" "=r")
4746 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4748 "andcc\\t%1, 0xff, %0"
4749 [(set_attr "type" "compare")
4750 (set_attr "length" "1")])
4752 (define_insn "*cmp_zero_extendqidi2"
4754 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4757 "andcc\\t%0, 0xff, %%g0"
4758 [(set_attr "type" "compare")
4759 (set_attr "length" "1")])
4761 (define_insn "*cmp_zero_qi_sp64"
4763 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4766 "andcc\\t%0, 0xff, %%g0"
4767 [(set_attr "type" "compare")
4768 (set_attr "length" "1")])
4770 (define_insn "*cmp_zero_extendqidi2_set"
4772 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4774 (set (match_operand:DI 0 "register_operand" "=r")
4775 (zero_extend:DI (match_dup 1)))]
4777 "andcc\\t%1, 0xff, %0"
4778 [(set_attr "type" "compare")
4779 (set_attr "length" "1")])
4781 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4783 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4786 (set (match_operand:DI 0 "register_operand" "=r")
4787 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4789 "andcc\\t%1, 0xff, %0"
4790 [(set_attr "type" "compare")
4791 (set_attr "length" "1")])
4793 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4795 (define_insn "*cmp_siqi_trunc"
4797 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
4800 "andcc\\t%0, 0xff, %%g0"
4801 [(set_attr "type" "compare")
4802 (set_attr "length" "1")])
4804 (define_insn "*cmp_siqi_trunc_set"
4806 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
4808 (set (match_operand:QI 0 "register_operand" "=r")
4809 (subreg:QI (match_dup 1) 0))]
4811 "andcc\\t%1, 0xff, %0"
4812 [(set_attr "type" "compare")
4813 (set_attr "length" "1")])
4815 (define_insn "*cmp_diqi_trunc"
4817 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 0)
4820 "andcc\\t%0, 0xff, %%g0"
4821 [(set_attr "type" "compare")
4822 (set_attr "length" "1")])
4824 (define_insn "*cmp_diqi_trunc_set"
4826 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0)
4828 (set (match_operand:QI 0 "register_operand" "=r")
4829 (subreg:QI (match_dup 1) 0))]
4831 "andcc\\t%1, 0xff, %0"
4832 [(set_attr "type" "compare")
4833 (set_attr "length" "1")])
4835 ;;- sign extension instructions
4837 ;; These patterns originally accepted general_operands, however, slightly
4838 ;; better code is generated by only accepting register_operands, and then
4839 ;; letting combine generate the lds[hb] insns.
4841 (define_expand "extendhisi2"
4842 [(set (match_operand:SI 0 "register_operand" "")
4843 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4847 rtx temp = gen_reg_rtx (SImode);
4848 rtx shift_16 = GEN_INT (16);
4849 int op1_subword = 0;
4851 if (GET_CODE (operand1) == SUBREG)
4853 op1_subword = SUBREG_WORD (operand1);
4854 operand1 = XEXP (operand1, 0);
4857 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4859 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4863 (define_insn "*sign_extendhisi2_insn"
4864 [(set (match_operand:SI 0 "register_operand" "=r")
4865 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4868 [(set_attr "type" "sload")
4869 (set_attr "length" "1")])
4871 (define_expand "extendqihi2"
4872 [(set (match_operand:HI 0 "register_operand" "")
4873 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4877 rtx temp = gen_reg_rtx (SImode);
4878 rtx shift_24 = GEN_INT (24);
4879 int op1_subword = 0;
4880 int op0_subword = 0;
4882 if (GET_CODE (operand1) == SUBREG)
4884 op1_subword = SUBREG_WORD (operand1);
4885 operand1 = XEXP (operand1, 0);
4887 if (GET_CODE (operand0) == SUBREG)
4889 op0_subword = SUBREG_WORD (operand0);
4890 operand0 = XEXP (operand0, 0);
4892 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4894 if (GET_MODE (operand0) != SImode)
4895 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subword);
4896 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4900 (define_insn "*sign_extendqihi2_insn"
4901 [(set (match_operand:HI 0 "register_operand" "=r")
4902 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4905 [(set_attr "type" "sload")
4906 (set_attr "length" "1")])
4908 (define_expand "extendqisi2"
4909 [(set (match_operand:SI 0 "register_operand" "")
4910 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4914 rtx temp = gen_reg_rtx (SImode);
4915 rtx shift_24 = GEN_INT (24);
4916 int op1_subword = 0;
4918 if (GET_CODE (operand1) == SUBREG)
4920 op1_subword = SUBREG_WORD (operand1);
4921 operand1 = XEXP (operand1, 0);
4924 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4926 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4930 (define_insn "*sign_extendqisi2_insn"
4931 [(set (match_operand:SI 0 "register_operand" "=r")
4932 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4935 [(set_attr "type" "sload")
4936 (set_attr "length" "1")])
4938 (define_expand "extendqidi2"
4939 [(set (match_operand:DI 0 "register_operand" "")
4940 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4944 rtx temp = gen_reg_rtx (DImode);
4945 rtx shift_56 = GEN_INT (56);
4946 int op1_subword = 0;
4948 if (GET_CODE (operand1) == SUBREG)
4950 op1_subword = SUBREG_WORD (operand1);
4951 operand1 = XEXP (operand1, 0);
4954 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4956 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4960 (define_insn "*sign_extendqidi2_insn"
4961 [(set (match_operand:DI 0 "register_operand" "=r")
4962 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4965 [(set_attr "type" "sload")
4966 (set_attr "length" "1")])
4968 (define_expand "extendhidi2"
4969 [(set (match_operand:DI 0 "register_operand" "")
4970 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4974 rtx temp = gen_reg_rtx (DImode);
4975 rtx shift_48 = GEN_INT (48);
4976 int op1_subword = 0;
4978 if (GET_CODE (operand1) == SUBREG)
4980 op1_subword = SUBREG_WORD (operand1);
4981 operand1 = XEXP (operand1, 0);
4984 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4986 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4990 (define_insn "*sign_extendhidi2_insn"
4991 [(set (match_operand:DI 0 "register_operand" "=r")
4992 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4995 [(set_attr "type" "sload")
4996 (set_attr "length" "1")])
4998 (define_expand "extendsidi2"
4999 [(set (match_operand:DI 0 "register_operand" "")
5000 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
5004 (define_insn "*sign_extendsidi2_insn"
5005 [(set (match_operand:DI 0 "register_operand" "=r,r")
5006 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
5011 [(set_attr "type" "shift,sload")
5012 (set_attr "length" "1")])
5014 ;; Special pattern for optimizing bit-field compares. This is needed
5015 ;; because combine uses this as a canonical form.
5017 (define_insn "*cmp_zero_extract"
5020 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
5021 (match_operand:SI 1 "small_int_or_double" "n")
5022 (match_operand:SI 2 "small_int_or_double" "n"))
5024 "(GET_CODE (operands[2]) == CONST_INT
5025 && INTVAL (operands[2]) > 19)
5026 || (GET_CODE (operands[2]) == CONST_DOUBLE
5027 && CONST_DOUBLE_LOW (operands[2]) > 19)"
5030 int len = (GET_CODE (operands[1]) == CONST_INT
5031 ? INTVAL (operands[1])
5032 : CONST_DOUBLE_LOW (operands[1]));
5034 (GET_CODE (operands[2]) == CONST_INT
5035 ? INTVAL (operands[2])
5036 : CONST_DOUBLE_LOW (operands[2])) - len;
5037 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
5039 operands[1] = GEN_INT (mask);
5040 return \"andcc\\t%0, %1, %%g0\";
5042 [(set_attr "type" "compare")
5043 (set_attr "length" "1")])
5045 (define_insn "*cmp_zero_extract_sp64"
5048 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
5049 (match_operand:SI 1 "small_int_or_double" "n")
5050 (match_operand:SI 2 "small_int_or_double" "n"))
5053 && ((GET_CODE (operands[2]) == CONST_INT
5054 && INTVAL (operands[2]) > 51)
5055 || (GET_CODE (operands[2]) == CONST_DOUBLE
5056 && CONST_DOUBLE_LOW (operands[2]) > 51))"
5059 int len = (GET_CODE (operands[1]) == CONST_INT
5060 ? INTVAL (operands[1])
5061 : CONST_DOUBLE_LOW (operands[1]));
5063 (GET_CODE (operands[2]) == CONST_INT
5064 ? INTVAL (operands[2])
5065 : CONST_DOUBLE_LOW (operands[2])) - len;
5066 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
5068 operands[1] = GEN_INT (mask);
5069 return \"andcc\\t%0, %1, %%g0\";
5071 [(set_attr "type" "compare")
5072 (set_attr "length" "1")])
5074 ;; Conversions between float, double and long double.
5076 (define_insn "extendsfdf2"
5077 [(set (match_operand:DF 0 "register_operand" "=e")
5079 (match_operand:SF 1 "register_operand" "f")))]
5082 [(set_attr "type" "fp")
5083 (set_attr "length" "1")])
5085 (define_expand "extendsftf2"
5086 [(set (match_operand:TF 0 "register_operand" "=e")
5088 (match_operand:SF 1 "register_operand" "f")))]
5089 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5092 if (! TARGET_HARD_QUAD)
5096 if (GET_CODE (operands[0]) != MEM)
5097 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5099 slot0 = operands[0];
5101 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
5103 XEXP (slot0, 0), Pmode,
5104 operands[1], SFmode);
5106 if (GET_CODE (operands[0]) != MEM)
5107 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5112 (define_insn "*extendsftf2_hq"
5113 [(set (match_operand:TF 0 "register_operand" "=e")
5115 (match_operand:SF 1 "register_operand" "f")))]
5116 "TARGET_FPU && TARGET_HARD_QUAD"
5118 [(set_attr "type" "fp")
5119 (set_attr "length" "1")])
5121 (define_expand "extenddftf2"
5122 [(set (match_operand:TF 0 "register_operand" "=e")
5124 (match_operand:DF 1 "register_operand" "e")))]
5125 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5128 if (! TARGET_HARD_QUAD)
5132 if (GET_CODE (operands[0]) != MEM)
5133 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5135 slot0 = operands[0];
5137 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5139 XEXP (slot0, 0), Pmode,
5140 operands[1], DFmode);
5142 if (GET_CODE (operands[0]) != MEM)
5143 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5148 (define_insn "*extenddftf2_hq"
5149 [(set (match_operand:TF 0 "register_operand" "=e")
5151 (match_operand:DF 1 "register_operand" "e")))]
5152 "TARGET_FPU && TARGET_HARD_QUAD"
5154 [(set_attr "type" "fp")
5155 (set_attr "length" "1")])
5157 (define_insn "truncdfsf2"
5158 [(set (match_operand:SF 0 "register_operand" "=f")
5160 (match_operand:DF 1 "register_operand" "e")))]
5163 [(set_attr "type" "fp")
5164 (set_attr "length" "1")])
5166 (define_expand "trunctfsf2"
5167 [(set (match_operand:SF 0 "register_operand" "=f")
5169 (match_operand:TF 1 "register_operand" "e")))]
5170 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5173 if (! TARGET_HARD_QUAD)
5177 if (GET_CODE (operands[1]) != MEM)
5179 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5180 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5183 slot0 = operands[1];
5185 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5186 operands[0], 0, SFmode, 1,
5187 XEXP (slot0, 0), Pmode);
5192 (define_insn "*trunctfsf2_hq"
5193 [(set (match_operand:SF 0 "register_operand" "=f")
5195 (match_operand:TF 1 "register_operand" "e")))]
5196 "TARGET_FPU && TARGET_HARD_QUAD"
5198 [(set_attr "type" "fp")
5199 (set_attr "length" "1")])
5201 (define_expand "trunctfdf2"
5202 [(set (match_operand:DF 0 "register_operand" "=f")
5204 (match_operand:TF 1 "register_operand" "e")))]
5205 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5208 if (! TARGET_HARD_QUAD)
5212 if (GET_CODE (operands[1]) != MEM)
5214 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5215 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5218 slot0 = operands[1];
5220 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5221 operands[0], 0, DFmode, 1,
5222 XEXP (slot0, 0), Pmode);
5227 (define_insn "*trunctfdf2_hq"
5228 [(set (match_operand:DF 0 "register_operand" "=e")
5230 (match_operand:TF 1 "register_operand" "e")))]
5231 "TARGET_FPU && TARGET_HARD_QUAD"
5233 [(set_attr "type" "fp")
5234 (set_attr "length" "1")])
5236 ;; Conversion between fixed point and floating point.
5238 (define_insn "floatsisf2"
5239 [(set (match_operand:SF 0 "register_operand" "=f")
5240 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5243 [(set_attr "type" "fp")
5244 (set_attr "length" "1")])
5246 (define_insn "floatsidf2"
5247 [(set (match_operand:DF 0 "register_operand" "=e")
5248 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5251 [(set_attr "type" "fp")
5252 (set_attr "length" "1")])
5254 (define_expand "floatsitf2"
5255 [(set (match_operand:TF 0 "register_operand" "=e")
5256 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5257 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5260 if (! TARGET_HARD_QUAD)
5264 if (GET_CODE (operands[1]) != MEM)
5265 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5267 slot0 = operands[1];
5269 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5271 XEXP (slot0, 0), Pmode,
5272 operands[1], SImode);
5274 if (GET_CODE (operands[0]) != MEM)
5275 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5280 (define_insn "*floatsitf2_hq"
5281 [(set (match_operand:TF 0 "register_operand" "=e")
5282 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5283 "TARGET_FPU && TARGET_HARD_QUAD"
5285 [(set_attr "type" "fp")
5286 (set_attr "length" "1")])
5288 (define_expand "floatunssitf2"
5289 [(set (match_operand:TF 0 "register_operand" "=e")
5290 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5291 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5296 if (GET_CODE (operands[1]) != MEM)
5297 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5299 slot0 = operands[1];
5301 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5303 XEXP (slot0, 0), Pmode,
5304 operands[1], SImode);
5306 if (GET_CODE (operands[0]) != MEM)
5307 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5311 ;; Now the same for 64 bit sources.
5313 (define_insn "floatdisf2"
5314 [(set (match_operand:SF 0 "register_operand" "=f")
5315 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5316 "TARGET_V9 && TARGET_FPU"
5318 [(set_attr "type" "fp")
5319 (set_attr "length" "1")])
5321 (define_insn "floatdidf2"
5322 [(set (match_operand:DF 0 "register_operand" "=e")
5323 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5324 "TARGET_V9 && TARGET_FPU"
5326 [(set_attr "type" "fp")
5327 (set_attr "length" "1")])
5329 (define_expand "floatditf2"
5330 [(set (match_operand:TF 0 "register_operand" "=e")
5331 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5332 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5335 if (! TARGET_HARD_QUAD)
5339 if (GET_CODE (operands[1]) != MEM)
5340 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5342 slot0 = operands[1];
5344 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5346 XEXP (slot0, 0), Pmode,
5347 operands[1], DImode);
5349 if (GET_CODE (operands[0]) != MEM)
5350 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5355 (define_insn "*floatditf2_hq"
5356 [(set (match_operand:TF 0 "register_operand" "=e")
5357 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5358 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5360 [(set_attr "type" "fp")
5361 (set_attr "length" "1")])
5363 (define_expand "floatunsditf2"
5364 [(set (match_operand:TF 0 "register_operand" "=e")
5365 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5366 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5371 if (GET_CODE (operands[1]) != MEM)
5372 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5374 slot0 = operands[1];
5376 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5378 XEXP (slot0, 0), Pmode,
5379 operands[1], DImode);
5381 if (GET_CODE (operands[0]) != MEM)
5382 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5386 ;; Convert a float to an actual integer.
5387 ;; Truncation is performed as part of the conversion.
5389 (define_insn "fix_truncsfsi2"
5390 [(set (match_operand:SI 0 "register_operand" "=f")
5391 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5394 [(set_attr "type" "fp")
5395 (set_attr "length" "1")])
5397 (define_insn "fix_truncdfsi2"
5398 [(set (match_operand:SI 0 "register_operand" "=f")
5399 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5402 [(set_attr "type" "fp")
5403 (set_attr "length" "1")])
5405 (define_expand "fix_trunctfsi2"
5406 [(set (match_operand:SI 0 "register_operand" "=f")
5407 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5408 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5411 if (! TARGET_HARD_QUAD)
5415 if (GET_CODE (operands[1]) != MEM)
5417 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5418 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5421 slot0 = operands[1];
5423 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5424 operands[0], 0, SImode, 1,
5425 XEXP (slot0, 0), Pmode);
5430 (define_insn "*fix_trunctfsi2_hq"
5431 [(set (match_operand:SI 0 "register_operand" "=f")
5432 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5433 "TARGET_FPU && TARGET_HARD_QUAD"
5435 [(set_attr "type" "fp")
5436 (set_attr "length" "1")])
5438 (define_expand "fixuns_trunctfsi2"
5439 [(set (match_operand:SI 0 "register_operand" "=f")
5440 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5441 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5446 if (GET_CODE (operands[1]) != MEM)
5448 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5449 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5452 slot0 = operands[1];
5454 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5455 operands[0], 0, SImode, 1,
5456 XEXP (slot0, 0), Pmode);
5460 ;; Now the same, for V9 targets
5462 (define_insn "fix_truncsfdi2"
5463 [(set (match_operand:DI 0 "register_operand" "=e")
5464 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5465 "TARGET_V9 && TARGET_FPU"
5467 [(set_attr "type" "fp")
5468 (set_attr "length" "1")])
5470 (define_insn "fix_truncdfdi2"
5471 [(set (match_operand:DI 0 "register_operand" "=e")
5472 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5473 "TARGET_V9 && TARGET_FPU"
5475 [(set_attr "type" "fp")
5476 (set_attr "length" "1")])
5478 (define_expand "fix_trunctfdi2"
5479 [(set (match_operand:DI 0 "register_operand" "=e")
5480 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5481 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5484 if (! TARGET_HARD_QUAD)
5488 if (GET_CODE (operands[1]) != MEM)
5490 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5491 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5494 slot0 = operands[1];
5496 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5497 operands[0], 0, DImode, 1,
5498 XEXP (slot0, 0), Pmode);
5503 (define_insn "*fix_trunctfdi2_hq"
5504 [(set (match_operand:DI 0 "register_operand" "=e")
5505 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5506 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5508 [(set_attr "type" "fp")
5509 (set_attr "length" "1")])
5511 (define_expand "fixuns_trunctfdi2"
5512 [(set (match_operand:DI 0 "register_operand" "=f")
5513 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5514 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5519 if (GET_CODE (operands[1]) != MEM)
5521 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5522 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5525 slot0 = operands[1];
5527 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5528 operands[0], 0, DImode, 1,
5529 XEXP (slot0, 0), Pmode);
5534 ;;- arithmetic instructions
5536 (define_expand "adddi3"
5537 [(set (match_operand:DI 0 "register_operand" "=r")
5538 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5539 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5545 if (! TARGET_ARCH64)
5547 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5548 gen_rtx_SET (VOIDmode, operands[0],
5549 gen_rtx_PLUS (DImode, operands[1],
5551 gen_rtx_CLOBBER (VOIDmode,
5552 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5555 if (arith_double_4096_operand(operands[2], DImode))
5557 switch (GET_CODE (operands[1]))
5559 case CONST_INT: i = INTVAL (operands[1]); break;
5560 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5562 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5563 gen_rtx_MINUS (DImode, operands[1],
5567 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5572 (define_insn "adddi3_insn_sp32"
5573 [(set (match_operand:DI 0 "register_operand" "=r")
5574 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5575 (match_operand:DI 2 "arith_double_operand" "rHI")))
5576 (clobber (reg:CC 100))]
5579 [(set_attr "length" "2")])
5582 [(set (match_operand:DI 0 "register_operand" "=r")
5583 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5584 (match_operand:DI 2 "arith_double_operand" "rHI")))
5585 (clobber (reg:CC 100))]
5586 "! TARGET_ARCH64 && reload_completed"
5587 [(parallel [(set (reg:CC_NOOV 100)
5588 (compare:CC_NOOV (plus:SI (match_dup 4)
5592 (plus:SI (match_dup 4) (match_dup 5)))])
5594 (plus:SI (plus:SI (match_dup 7)
5596 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5599 operands[3] = gen_lowpart (SImode, operands[0]);
5600 operands[4] = gen_lowpart (SImode, operands[1]);
5601 operands[5] = gen_lowpart (SImode, operands[2]);
5602 operands[6] = gen_highpart (SImode, operands[0]);
5603 operands[7] = gen_highpart (SImode, operands[1]);
5604 #if HOST_BITS_PER_WIDE_INT == 32
5605 if (GET_CODE (operands[2]) == CONST_INT)
5607 if (INTVAL (operands[2]) < 0)
5608 operands[8] = constm1_rtx;
5610 operands[8] = const0_rtx;
5614 operands[8] = gen_highpart (SImode, operands[2]);
5618 [(set (match_operand:DI 0 "register_operand" "=r")
5619 (minus:DI (match_operand:DI 1 "arith_double_operand" "r")
5620 (match_operand:DI 2 "arith_double_operand" "rHI")))
5621 (clobber (reg:CC 100))]
5622 "! TARGET_ARCH64 && reload_completed"
5623 [(parallel [(set (reg:CC_NOOV 100)
5624 (compare:CC_NOOV (minus:SI (match_dup 4)
5628 (minus:SI (match_dup 4) (match_dup 5)))])
5630 (minus:SI (minus:SI (match_dup 7)
5632 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5635 operands[3] = gen_lowpart (SImode, operands[0]);
5636 operands[4] = gen_lowpart (SImode, operands[1]);
5637 operands[5] = gen_lowpart (SImode, operands[2]);
5638 operands[6] = gen_highpart (SImode, operands[0]);
5639 operands[7] = gen_highpart (SImode, operands[1]);
5640 #if HOST_BITS_PER_WIDE_INT == 32
5641 if (GET_CODE (operands[2]) == CONST_INT)
5643 if (INTVAL (operands[2]) < 0)
5644 operands[8] = constm1_rtx;
5646 operands[8] = const0_rtx;
5650 operands[8] = gen_highpart (SImode, operands[2]);
5653 ;; LTU here means "carry set"
5655 [(set (match_operand:SI 0 "register_operand" "=r")
5656 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5657 (match_operand:SI 2 "arith_operand" "rI"))
5658 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5661 [(set_attr "type" "unary")
5662 (set_attr "length" "1")])
5664 (define_insn "*addx_extend_sp32"
5665 [(set (match_operand:DI 0 "register_operand" "=r")
5666 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5667 (match_operand:SI 2 "arith_operand" "rI"))
5668 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5671 [(set_attr "type" "unary")
5672 (set_attr "length" "2")])
5675 [(set (match_operand:DI 0 "register_operand" "")
5676 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5677 (match_operand:SI 2 "arith_operand" ""))
5678 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5679 "! TARGET_ARCH64 && reload_completed"
5680 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5681 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5682 (set (match_dup 4) (const_int 0))]
5683 "operands[3] = gen_lowpart (SImode, operands[0]);
5684 operands[4] = gen_highpart (SImode, operands[1]);")
5686 (define_insn "*addx_extend_sp64"
5687 [(set (match_operand:DI 0 "register_operand" "=r")
5688 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5689 (match_operand:SI 2 "arith_operand" "rI"))
5690 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5692 "addx\\t%r1, %2, %0"
5693 [(set_attr "type" "misc")
5694 (set_attr "length" "1")])
5697 [(set (match_operand:SI 0 "register_operand" "=r")
5698 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5699 (match_operand:SI 2 "arith_operand" "rI"))
5700 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5702 "subx\\t%r1, %2, %0"
5703 [(set_attr "type" "misc")
5704 (set_attr "length" "1")])
5706 (define_insn "*subx_extend_sp64"
5707 [(set (match_operand:DI 0 "register_operand" "=r")
5708 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5709 (match_operand:SI 2 "arith_operand" "rI"))
5710 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5712 "subx\\t%r1, %2, %0"
5713 [(set_attr "type" "misc")
5714 (set_attr "length" "1")])
5716 (define_insn "*subx_extend"
5717 [(set (match_operand:DI 0 "register_operand" "=r")
5718 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5719 (match_operand:SI 2 "arith_operand" "rI"))
5720 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5723 [(set_attr "type" "unary")
5724 (set_attr "length" "2")])
5727 [(set (match_operand:DI 0 "register_operand" "=r")
5728 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5729 (match_operand:SI 2 "arith_operand" "rI"))
5730 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5731 "! TARGET_ARCH64 && reload_completed"
5732 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5733 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5734 (set (match_dup 4) (const_int 0))]
5735 "operands[3] = gen_lowpart (SImode, operands[0]);
5736 operands[4] = gen_highpart (SImode, operands[0]);")
5739 [(set (match_operand:DI 0 "register_operand" "=r")
5740 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5741 (match_operand:DI 2 "register_operand" "r")))
5742 (clobber (reg:CC 100))]
5745 [(set_attr "type" "multi")
5746 (set_attr "length" "2")])
5749 [(set (match_operand:DI 0 "register_operand" "")
5750 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5751 (match_operand:DI 2 "register_operand" "")))
5752 (clobber (reg:CC 100))]
5753 "! TARGET_ARCH64 && reload_completed"
5754 [(parallel [(set (reg:CC_NOOV 100)
5755 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5757 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5759 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5760 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5761 "operands[3] = gen_lowpart (SImode, operands[2]);
5762 operands[4] = gen_highpart (SImode, operands[2]);
5763 operands[5] = gen_lowpart (SImode, operands[0]);
5764 operands[6] = gen_highpart (SImode, operands[0]);")
5766 (define_insn "*adddi3_sp64"
5767 [(set (match_operand:DI 0 "register_operand" "=r")
5768 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5769 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5772 [(set_attr "type" "binary")
5773 (set_attr "length" "1")])
5775 (define_expand "addsi3"
5776 [(set (match_operand:SI 0 "register_operand" "=r,d")
5777 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5778 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5782 if (arith_4096_operand(operands[2], SImode))
5784 if (GET_CODE (operands[1]) == CONST_INT)
5785 emit_insn (gen_movsi (operands[0],
5786 GEN_INT (INTVAL (operands[1]) + 4096)));
5788 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5789 gen_rtx_MINUS (SImode, operands[1],
5795 (define_insn "*addsi3"
5796 [(set (match_operand:SI 0 "register_operand" "=r,d")
5797 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5798 (match_operand:SI 2 "arith_operand" "rI,d")))]
5802 fpadd32s\\t%1, %2, %0"
5803 [(set_attr "type" "ialu,fp")
5804 (set_attr "length" "1")])
5806 (define_insn "*cmp_cc_plus"
5807 [(set (reg:CC_NOOV 100)
5808 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5809 (match_operand:SI 1 "arith_operand" "rI"))
5812 "addcc\\t%0, %1, %%g0"
5813 [(set_attr "type" "compare")
5814 (set_attr "length" "1")])
5816 (define_insn "*cmp_ccx_plus"
5817 [(set (reg:CCX_NOOV 100)
5818 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5819 (match_operand:DI 1 "arith_double_operand" "rHI"))
5822 "addcc\\t%0, %1, %%g0"
5823 [(set_attr "type" "compare")
5824 (set_attr "length" "1")])
5826 (define_insn "*cmp_cc_plus_set"
5827 [(set (reg:CC_NOOV 100)
5828 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5829 (match_operand:SI 2 "arith_operand" "rI"))
5831 (set (match_operand:SI 0 "register_operand" "=r")
5832 (plus:SI (match_dup 1) (match_dup 2)))]
5834 "addcc\\t%1, %2, %0"
5835 [(set_attr "type" "compare")
5836 (set_attr "length" "1")])
5838 (define_insn "*cmp_ccx_plus_set"
5839 [(set (reg:CCX_NOOV 100)
5840 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5841 (match_operand:DI 2 "arith_double_operand" "rHI"))
5843 (set (match_operand:DI 0 "register_operand" "=r")
5844 (plus:DI (match_dup 1) (match_dup 2)))]
5846 "addcc\\t%1, %2, %0"
5847 [(set_attr "type" "compare")
5848 (set_attr "length" "1")])
5850 (define_expand "subdi3"
5851 [(set (match_operand:DI 0 "register_operand" "=r")
5852 (minus:DI (match_operand:DI 1 "register_operand" "r")
5853 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5857 if (! TARGET_ARCH64)
5859 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5860 gen_rtx_SET (VOIDmode, operands[0],
5861 gen_rtx_MINUS (DImode, operands[1],
5863 gen_rtx_CLOBBER (VOIDmode,
5864 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5867 if (arith_double_4096_operand(operands[2], DImode))
5869 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5870 gen_rtx_PLUS (DImode, operands[1],
5876 (define_insn "*subdi3_sp32"
5877 [(set (match_operand:DI 0 "register_operand" "=r")
5878 (minus:DI (match_operand:DI 1 "register_operand" "r")
5879 (match_operand:DI 2 "arith_double_operand" "rHI")))
5880 (clobber (reg:CC 100))]
5883 [(set_attr "length" "2")])
5886 [(set (match_operand:DI 0 "register_operand" "")
5887 (minus:DI (match_operand:DI 1 "register_operand" "")
5888 (match_operand:DI 2 "arith_double_operand" "")))
5889 (clobber (reg:CC 100))]
5892 && (GET_CODE (operands[2]) == CONST_INT
5893 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5894 [(clobber (const_int 0))]
5899 highp = gen_highpart (SImode, operands[2]);
5900 lowp = gen_lowpart (SImode, operands[2]);
5901 if ((lowp == const0_rtx)
5902 && (operands[0] == operands[1]))
5904 emit_insn (gen_rtx_SET (VOIDmode,
5905 gen_highpart (SImode, operands[0]),
5906 gen_rtx_MINUS (SImode,
5907 gen_highpart (SImode, operands[1]),
5912 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5913 gen_lowpart (SImode, operands[1]),
5915 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5916 gen_highpart (SImode, operands[1]),
5923 [(set (match_operand:DI 0 "register_operand" "")
5924 (minus:DI (match_operand:DI 1 "register_operand" "")
5925 (match_operand:DI 2 "register_operand" "")))
5926 (clobber (reg:CC 100))]
5928 && reload_completed"
5929 [(clobber (const_int 0))]
5932 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5933 gen_lowpart (SImode, operands[1]),
5934 gen_lowpart (SImode, operands[2])));
5935 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5936 gen_highpart (SImode, operands[1]),
5937 gen_highpart (SImode, operands[2])));
5942 [(set (match_operand:DI 0 "register_operand" "=r")
5943 (minus:DI (match_operand:DI 1 "register_operand" "r")
5944 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5945 (clobber (reg:CC 100))]
5948 [(set_attr "type" "multi")
5949 (set_attr "length" "2")])
5952 [(set (match_operand:DI 0 "register_operand" "")
5953 (minus:DI (match_operand:DI 1 "register_operand" "")
5954 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5955 (clobber (reg:CC 100))]
5956 "! TARGET_ARCH64 && reload_completed"
5957 [(parallel [(set (reg:CC_NOOV 100)
5958 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5960 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5962 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5963 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5964 "operands[3] = gen_lowpart (SImode, operands[1]);
5965 operands[4] = gen_highpart (SImode, operands[1]);
5966 operands[5] = gen_lowpart (SImode, operands[0]);
5967 operands[6] = gen_highpart (SImode, operands[0]);")
5969 (define_insn "*subdi3_sp64"
5970 [(set (match_operand:DI 0 "register_operand" "=r")
5971 (minus:DI (match_operand:DI 1 "register_operand" "r")
5972 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5975 [(set_attr "type" "binary")
5976 (set_attr "length" "1")])
5978 (define_expand "subsi3"
5979 [(set (match_operand:SI 0 "register_operand" "=r,d")
5980 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5981 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5985 if (arith_4096_operand(operands[2], SImode))
5987 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5988 gen_rtx_PLUS (SImode, operands[1],
5994 (define_insn "*subsi3"
5995 [(set (match_operand:SI 0 "register_operand" "=r,d")
5996 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5997 (match_operand:SI 2 "arith_operand" "rI,d")))]
6001 fpsub32s\\t%1, %2, %0"
6002 [(set_attr "type" "ialu,fp")
6003 (set_attr "length" "1")])
6005 (define_insn "*cmp_minus_cc"
6006 [(set (reg:CC_NOOV 100)
6007 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
6008 (match_operand:SI 1 "arith_operand" "rI"))
6011 "subcc\\t%r0, %1, %%g0"
6012 [(set_attr "type" "compare")
6013 (set_attr "length" "1")])
6015 (define_insn "*cmp_minus_ccx"
6016 [(set (reg:CCX_NOOV 100)
6017 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
6018 (match_operand:DI 1 "arith_double_operand" "rHI"))
6021 "subcc\\t%0, %1, %%g0"
6022 [(set_attr "type" "compare")
6023 (set_attr "length" "1")])
6025 (define_insn "cmp_minus_cc_set"
6026 [(set (reg:CC_NOOV 100)
6027 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
6028 (match_operand:SI 2 "arith_operand" "rI"))
6030 (set (match_operand:SI 0 "register_operand" "=r")
6031 (minus:SI (match_dup 1) (match_dup 2)))]
6033 "subcc\\t%r1, %2, %0"
6034 [(set_attr "type" "compare")
6035 (set_attr "length" "1")])
6037 (define_insn "*cmp_minus_ccx_set"
6038 [(set (reg:CCX_NOOV 100)
6039 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
6040 (match_operand:DI 2 "arith_double_operand" "rHI"))
6042 (set (match_operand:DI 0 "register_operand" "=r")
6043 (minus:DI (match_dup 1) (match_dup 2)))]
6045 "subcc\\t%1, %2, %0"
6046 [(set_attr "type" "compare")
6047 (set_attr "length" "1")])
6049 ;; Integer Multiply/Divide.
6051 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
6052 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
6054 (define_insn "mulsi3"
6055 [(set (match_operand:SI 0 "register_operand" "=r")
6056 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6057 (match_operand:SI 2 "arith_operand" "rI")))]
6060 [(set_attr "type" "imul")
6061 (set_attr "length" "1")])
6063 (define_expand "muldi3"
6064 [(set (match_operand:DI 0 "register_operand" "=r")
6065 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6066 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6067 "TARGET_ARCH64 || TARGET_V8PLUS"
6072 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
6077 (define_insn "*muldi3_sp64"
6078 [(set (match_operand:DI 0 "register_operand" "=r")
6079 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6080 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6083 [(set_attr "type" "imul")
6084 (set_attr "length" "1")])
6086 ;; V8plus wide multiply.
6088 (define_insn "muldi3_v8plus"
6089 [(set (match_operand:DI 0 "register_operand" "=r,h")
6090 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
6091 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
6092 (clobber (match_scratch:SI 3 "=&h,X"))
6093 (clobber (match_scratch:SI 4 "=&h,X"))]
6097 if (sparc_check_64 (operands[1], insn) <= 0)
6098 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
6099 if (which_alternative == 1)
6100 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
6101 if (GET_CODE (operands[2]) == CONST_INT)
6103 if (which_alternative == 1)
6104 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
6106 return \"sllx\\t%H1, 32, %3\\n\\tor\\t%L1, %3, %3\\n\\tmulx\\t%3, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\";
6108 if (sparc_check_64 (operands[2], insn) <= 0)
6109 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6110 if (which_alternative == 1)
6111 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\";
6113 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\";
6115 [(set_attr "length" "9,8")])
6117 (define_insn "*cmp_mul_set"
6119 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6120 (match_operand:SI 2 "arith_operand" "rI"))
6122 (set (match_operand:SI 0 "register_operand" "=r")
6123 (mult:SI (match_dup 1) (match_dup 2)))]
6124 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6125 "smulcc\\t%1, %2, %0"
6126 [(set_attr "type" "imul")
6127 (set_attr "length" "1")])
6129 (define_expand "mulsidi3"
6130 [(set (match_operand:DI 0 "register_operand" "")
6131 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6132 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6136 if (CONSTANT_P (operands[2]))
6139 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6142 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6148 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6153 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6154 ;; registers can hold 64 bit values in the V8plus environment.
6156 (define_insn "mulsidi3_v8plus"
6157 [(set (match_operand:DI 0 "register_operand" "=h,r")
6158 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6159 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6160 (clobber (match_scratch:SI 3 "=X,&h"))]
6163 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6164 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6165 [(set_attr "length" "2,3")])
6168 (define_insn "const_mulsidi3_v8plus"
6169 [(set (match_operand:DI 0 "register_operand" "=h,r")
6170 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6171 (match_operand:SI 2 "small_int" "I,I")))
6172 (clobber (match_scratch:SI 3 "=X,&h"))]
6175 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6176 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6177 [(set_attr "length" "2,3")])
6180 (define_insn "*mulsidi3_sp32"
6181 [(set (match_operand:DI 0 "register_operand" "=r")
6182 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6183 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6187 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6189 [(set (attr "length")
6190 (if_then_else (eq_attr "isa" "sparclet")
6191 (const_int 1) (const_int 2)))])
6193 (define_insn "*mulsidi3_sp64"
6194 [(set (match_operand:DI 0 "register_operand" "=r")
6195 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6196 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6197 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6199 [(set_attr "length" "1")])
6201 ;; Extra pattern, because sign_extend of a constant isn't valid.
6204 (define_insn "const_mulsidi3_sp32"
6205 [(set (match_operand:DI 0 "register_operand" "=r")
6206 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6207 (match_operand:SI 2 "small_int" "I")))]
6211 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6213 [(set (attr "length")
6214 (if_then_else (eq_attr "isa" "sparclet")
6215 (const_int 1) (const_int 2)))])
6217 (define_insn "const_mulsidi3_sp64"
6218 [(set (match_operand:DI 0 "register_operand" "=r")
6219 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6220 (match_operand:SI 2 "small_int" "I")))]
6221 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6223 [(set_attr "length" "1")])
6225 (define_expand "smulsi3_highpart"
6226 [(set (match_operand:SI 0 "register_operand" "")
6228 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6229 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6231 "TARGET_HARD_MUL && TARGET_ARCH32"
6234 if (CONSTANT_P (operands[2]))
6238 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6244 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6249 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6250 operands[2], GEN_INT (32)));
6256 (define_insn "smulsi3_highpart_v8plus"
6257 [(set (match_operand:SI 0 "register_operand" "=h,r")
6259 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6260 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6261 (match_operand:SI 3 "const_int_operand" "i,i"))))
6262 (clobber (match_scratch:SI 4 "=X,&h"))]
6265 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6266 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6267 [(set_attr "length" "2")])
6269 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6272 [(set (match_operand:SI 0 "register_operand" "=h,r")
6275 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6276 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6277 (match_operand:SI 3 "const_int_operand" "i,i"))
6279 (clobber (match_scratch:SI 4 "=X,&h"))]
6282 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6283 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6284 [(set_attr "length" "2")])
6287 (define_insn "const_smulsi3_highpart_v8plus"
6288 [(set (match_operand:SI 0 "register_operand" "=h,r")
6290 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6291 (match_operand 2 "small_int" "i,i"))
6292 (match_operand:SI 3 "const_int_operand" "i,i"))))
6293 (clobber (match_scratch:SI 4 "=X,&h"))]
6296 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6297 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6298 [(set_attr "length" "2")])
6301 (define_insn "*smulsi3_highpart_sp32"
6302 [(set (match_operand:SI 0 "register_operand" "=r")
6304 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6305 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6308 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6309 [(set_attr "length" "2")])
6312 (define_insn "const_smulsi3_highpart"
6313 [(set (match_operand:SI 0 "register_operand" "=r")
6315 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6316 (match_operand:SI 2 "register_operand" "r"))
6319 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6320 [(set_attr "length" "2")])
6322 (define_expand "umulsidi3"
6323 [(set (match_operand:DI 0 "register_operand" "")
6324 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6325 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6329 if (CONSTANT_P (operands[2]))
6332 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6335 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6341 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6347 (define_insn "umulsidi3_v8plus"
6348 [(set (match_operand:DI 0 "register_operand" "=h,r")
6349 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6350 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6351 (clobber (match_scratch:SI 3 "=X,&h"))]
6354 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6355 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6356 [(set_attr "length" "2,3")])
6359 (define_insn "*umulsidi3_sp32"
6360 [(set (match_operand:DI 0 "register_operand" "=r")
6361 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6362 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6366 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6368 [(set (attr "length")
6369 (if_then_else (eq_attr "isa" "sparclet")
6370 (const_int 1) (const_int 2)))])
6372 (define_insn "*umulsidi3_sp64"
6373 [(set (match_operand:DI 0 "register_operand" "=r")
6374 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6375 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6376 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6378 [(set_attr "length" "1")])
6380 ;; Extra pattern, because sign_extend of a constant isn't valid.
6383 (define_insn "const_umulsidi3_sp32"
6384 [(set (match_operand:DI 0 "register_operand" "=r")
6385 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6386 (match_operand:SI 2 "uns_small_int" "")))]
6390 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6392 [(set (attr "length")
6393 (if_then_else (eq_attr "isa" "sparclet")
6394 (const_int 1) (const_int 2)))])
6396 (define_insn "const_umulsidi3_sp64"
6397 [(set (match_operand:DI 0 "register_operand" "=r")
6398 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6399 (match_operand:SI 2 "uns_small_int" "")))]
6400 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6402 [(set_attr "length" "1")])
6405 (define_insn "const_umulsidi3_v8plus"
6406 [(set (match_operand:DI 0 "register_operand" "=h,r")
6407 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6408 (match_operand:SI 2 "uns_small_int" "")))
6409 (clobber (match_scratch:SI 3 "=X,h"))]
6412 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6413 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6414 [(set_attr "length" "2,3")])
6416 (define_expand "umulsi3_highpart"
6417 [(set (match_operand:SI 0 "register_operand" "")
6419 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6420 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6422 "TARGET_HARD_MUL && TARGET_ARCH32"
6425 if (CONSTANT_P (operands[2]))
6429 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6435 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6440 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6441 operands[2], GEN_INT (32)));
6447 (define_insn "umulsi3_highpart_v8plus"
6448 [(set (match_operand:SI 0 "register_operand" "=h,r")
6450 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6451 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6452 (match_operand:SI 3 "const_int_operand" "i,i"))))
6453 (clobber (match_scratch:SI 4 "=X,h"))]
6456 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6457 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6458 [(set_attr "length" "2")])
6461 (define_insn "const_umulsi3_highpart_v8plus"
6462 [(set (match_operand:SI 0 "register_operand" "=h,r")
6464 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6465 (match_operand:SI 2 "uns_small_int" ""))
6466 (match_operand:SI 3 "const_int_operand" "i,i"))))
6467 (clobber (match_scratch:SI 4 "=X,h"))]
6470 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6471 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6472 [(set_attr "length" "2")])
6475 (define_insn "*umulsi3_highpart_sp32"
6476 [(set (match_operand:SI 0 "register_operand" "=r")
6478 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6479 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6482 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6483 [(set_attr "length" "2")])
6486 (define_insn "const_umulsi3_highpart"
6487 [(set (match_operand:SI 0 "register_operand" "=r")
6489 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6490 (match_operand:SI 2 "uns_small_int" ""))
6493 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6494 [(set_attr "length" "2")])
6496 ;; The v8 architecture specifies that there must be 3 instructions between
6497 ;; a y register write and a use of it for correct results.
6499 (define_expand "divsi3"
6500 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6501 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6502 (match_operand:SI 2 "input_operand" "rI,m")))
6503 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6504 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6509 operands[3] = gen_reg_rtx(SImode);
6510 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6511 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6517 (define_insn "divsi3_sp32"
6518 [(set (match_operand:SI 0 "register_operand" "=r,r")
6519 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6520 (match_operand:SI 2 "input_operand" "rI,m")))
6521 (clobber (match_scratch:SI 3 "=&r,&r"))]
6522 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6526 if (which_alternative == 0)
6528 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6530 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6533 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6535 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\";
6537 [(set (attr "length")
6538 (if_then_else (eq_attr "isa" "v9")
6539 (const_int 4) (const_int 7)))])
6541 (define_insn "divsi3_sp64"
6542 [(set (match_operand:SI 0 "register_operand" "=r")
6543 (div:SI (match_operand:SI 1 "register_operand" "r")
6544 (match_operand:SI 2 "input_operand" "rI")))
6545 (use (match_operand:SI 3 "register_operand" "r"))]
6546 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6547 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6548 [(set_attr "length" "2")])
6550 (define_insn "divdi3"
6551 [(set (match_operand:DI 0 "register_operand" "=r")
6552 (div:DI (match_operand:DI 1 "register_operand" "r")
6553 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6555 "sdivx\\t%1, %2, %0")
6557 (define_insn "*cmp_sdiv_cc_set"
6559 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6560 (match_operand:SI 2 "arith_operand" "rI"))
6562 (set (match_operand:SI 0 "register_operand" "=r")
6563 (div:SI (match_dup 1) (match_dup 2)))
6564 (clobber (match_scratch:SI 3 "=&r"))]
6565 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6569 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6571 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6573 [(set (attr "length")
6574 (if_then_else (eq_attr "isa" "v9")
6575 (const_int 3) (const_int 6)))])
6578 (define_expand "udivsi3"
6579 [(set (match_operand:SI 0 "register_operand" "")
6580 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6581 (match_operand:SI 2 "input_operand" "")))]
6582 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6585 (define_insn "udivsi3_sp32"
6586 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6587 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6588 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6590 || TARGET_DEPRECATED_V8_INSNS)
6594 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6595 switch (which_alternative)
6598 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6600 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6602 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6605 [(set_attr "length" "5")])
6607 (define_insn "udivsi3_sp64"
6608 [(set (match_operand:SI 0 "register_operand" "=r")
6609 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6610 (match_operand:SI 2 "input_operand" "rI")))]
6611 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6612 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6613 [(set_attr "length" "2")])
6615 (define_insn "udivdi3"
6616 [(set (match_operand:DI 0 "register_operand" "=r")
6617 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6618 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6620 "udivx\\t%1, %2, %0")
6622 (define_insn "*cmp_udiv_cc_set"
6624 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6625 (match_operand:SI 2 "arith_operand" "rI"))
6627 (set (match_operand:SI 0 "register_operand" "=r")
6628 (udiv:SI (match_dup 1) (match_dup 2)))]
6630 || TARGET_DEPRECATED_V8_INSNS"
6634 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6636 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6638 [(set (attr "length")
6639 (if_then_else (eq_attr "isa" "v9")
6640 (const_int 2) (const_int 5)))])
6642 ; sparclet multiply/accumulate insns
6644 (define_insn "*smacsi"
6645 [(set (match_operand:SI 0 "register_operand" "=r")
6646 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6647 (match_operand:SI 2 "arith_operand" "rI"))
6648 (match_operand:SI 3 "register_operand" "0")))]
6651 [(set_attr "type" "imul")
6652 (set_attr "length" "1")])
6654 (define_insn "*smacdi"
6655 [(set (match_operand:DI 0 "register_operand" "=r")
6656 (plus:DI (mult:DI (sign_extend:DI
6657 (match_operand:SI 1 "register_operand" "%r"))
6659 (match_operand:SI 2 "register_operand" "r")))
6660 (match_operand:DI 3 "register_operand" "0")))]
6662 "smacd\\t%1, %2, %L0"
6663 [(set_attr "type" "imul")
6664 (set_attr "length" "1")])
6666 (define_insn "*umacdi"
6667 [(set (match_operand:DI 0 "register_operand" "=r")
6668 (plus:DI (mult:DI (zero_extend:DI
6669 (match_operand:SI 1 "register_operand" "%r"))
6671 (match_operand:SI 2 "register_operand" "r")))
6672 (match_operand:DI 3 "register_operand" "0")))]
6674 "umacd\\t%1, %2, %L0"
6675 [(set_attr "type" "imul")
6676 (set_attr "length" "1")])
6678 ;;- Boolean instructions
6679 ;; We define DImode `and' so with DImode `not' we can get
6680 ;; DImode `andn'. Other combinations are possible.
6682 (define_expand "anddi3"
6683 [(set (match_operand:DI 0 "register_operand" "")
6684 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6685 (match_operand:DI 2 "arith_double_operand" "")))]
6689 (define_insn "*anddi3_sp32"
6690 [(set (match_operand:DI 0 "register_operand" "=r,b")
6691 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6692 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6697 [(set_attr "type" "ialu,fp")
6698 (set_attr "length" "2,1")])
6700 (define_insn "*anddi3_sp64"
6701 [(set (match_operand:DI 0 "register_operand" "=r,b")
6702 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6703 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6708 [(set_attr "type" "ialu,fp")
6709 (set_attr "length" "1,1")])
6711 (define_insn "andsi3"
6712 [(set (match_operand:SI 0 "register_operand" "=r,d")
6713 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6714 (match_operand:SI 2 "arith_operand" "rI,d")))]
6719 [(set_attr "type" "ialu,fp")
6720 (set_attr "length" "1,1")])
6723 [(set (match_operand:SI 0 "register_operand" "")
6724 (and:SI (match_operand:SI 1 "register_operand" "")
6725 (match_operand:SI 2 "" "")))
6726 (clobber (match_operand:SI 3 "register_operand" ""))]
6727 "GET_CODE (operands[2]) == CONST_INT
6728 && !SMALL_INT32 (operands[2])
6729 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6730 [(set (match_dup 3) (match_dup 4))
6731 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6734 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6737 ;; Split DImode logical operations requiring two instructions.
6739 [(set (match_operand:DI 0 "register_operand" "")
6740 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6741 [(match_operand:DI 2 "register_operand" "")
6742 (match_operand:DI 3 "arith_double_operand" "")]))]
6745 && ((GET_CODE (operands[0]) == REG
6746 && REGNO (operands[0]) < 32)
6747 || (GET_CODE (operands[0]) == SUBREG
6748 && GET_CODE (SUBREG_REG (operands[0])) == REG
6749 && REGNO (SUBREG_REG (operands[0])) < 32))"
6750 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6751 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6754 if (GET_CODE (operands[0]) == SUBREG)
6755 operands[0] = alter_subreg (operands[0]);
6756 operands[4] = gen_highpart (SImode, operands[0]);
6757 operands[5] = gen_lowpart (SImode, operands[0]);
6758 operands[6] = gen_highpart (SImode, operands[2]);
6759 operands[7] = gen_lowpart (SImode, operands[2]);
6760 #if HOST_BITS_PER_WIDE_INT == 32
6761 if (GET_CODE (operands[3]) == CONST_INT)
6763 if (INTVAL (operands[3]) < 0)
6764 operands[8] = constm1_rtx;
6766 operands[8] = const0_rtx;
6770 operands[8] = gen_highpart (SImode, operands[3]);
6771 operands[9] = gen_lowpart (SImode, operands[3]);
6774 (define_insn "*and_not_di_sp32"
6775 [(set (match_operand:DI 0 "register_operand" "=r,b")
6776 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6777 (match_operand:DI 2 "register_operand" "r,b")))]
6781 fandnot1\\t%1, %2, %0"
6782 [(set_attr "type" "ialu,fp")
6783 (set_attr "length" "2,1")])
6786 [(set (match_operand:DI 0 "register_operand" "")
6787 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6788 (match_operand:DI 2 "register_operand" "")))]
6791 && ((GET_CODE (operands[0]) == REG
6792 && REGNO (operands[0]) < 32)
6793 || (GET_CODE (operands[0]) == SUBREG
6794 && GET_CODE (SUBREG_REG (operands[0])) == REG
6795 && REGNO (SUBREG_REG (operands[0])) < 32))"
6796 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6797 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6798 "if (GET_CODE (operands[0]) == SUBREG)
6799 operands[0] = alter_subreg (operands[0]);
6800 operands[3] = gen_highpart (SImode, operands[0]);
6801 operands[4] = gen_highpart (SImode, operands[1]);
6802 operands[5] = gen_highpart (SImode, operands[2]);
6803 operands[6] = gen_lowpart (SImode, operands[0]);
6804 operands[7] = gen_lowpart (SImode, operands[1]);
6805 operands[8] = gen_lowpart (SImode, operands[2]);")
6807 (define_insn "*and_not_di_sp64"
6808 [(set (match_operand:DI 0 "register_operand" "=r,b")
6809 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6810 (match_operand:DI 2 "register_operand" "r,b")))]
6814 fandnot1\\t%1, %2, %0"
6815 [(set_attr "type" "ialu,fp")
6816 (set_attr "length" "1,1")])
6818 (define_insn "*and_not_si"
6819 [(set (match_operand:SI 0 "register_operand" "=r,d")
6820 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6821 (match_operand:SI 2 "register_operand" "r,d")))]
6825 fandnot1s\\t%1, %2, %0"
6826 [(set_attr "type" "ialu,fp")
6827 (set_attr "length" "1,1")])
6829 (define_expand "iordi3"
6830 [(set (match_operand:DI 0 "register_operand" "")
6831 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6832 (match_operand:DI 2 "arith_double_operand" "")))]
6836 (define_insn "*iordi3_sp32"
6837 [(set (match_operand:DI 0 "register_operand" "=r,b")
6838 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6839 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6844 [(set_attr "type" "ialu,fp")
6845 (set_attr "length" "2,1")])
6847 (define_insn "*iordi3_sp64"
6848 [(set (match_operand:DI 0 "register_operand" "=r,b")
6849 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6850 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6855 [(set_attr "type" "ialu,fp")
6856 (set_attr "length" "1,1")])
6858 (define_insn "iorsi3"
6859 [(set (match_operand:SI 0 "register_operand" "=r,d")
6860 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6861 (match_operand:SI 2 "arith_operand" "rI,d")))]
6866 [(set_attr "type" "ialu,fp")
6867 (set_attr "length" "1,1")])
6870 [(set (match_operand:SI 0 "register_operand" "")
6871 (ior:SI (match_operand:SI 1 "register_operand" "")
6872 (match_operand:SI 2 "" "")))
6873 (clobber (match_operand:SI 3 "register_operand" ""))]
6874 "GET_CODE (operands[2]) == CONST_INT
6875 && !SMALL_INT32 (operands[2])
6876 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6877 [(set (match_dup 3) (match_dup 4))
6878 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6881 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6884 (define_insn "*or_not_di_sp32"
6885 [(set (match_operand:DI 0 "register_operand" "=r,b")
6886 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6887 (match_operand:DI 2 "register_operand" "r,b")))]
6891 fornot1\\t%1, %2, %0"
6892 [(set_attr "type" "ialu,fp")
6893 (set_attr "length" "2,1")])
6896 [(set (match_operand:DI 0 "register_operand" "")
6897 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6898 (match_operand:DI 2 "register_operand" "")))]
6901 && ((GET_CODE (operands[0]) == REG
6902 && REGNO (operands[0]) < 32)
6903 || (GET_CODE (operands[0]) == SUBREG
6904 && GET_CODE (SUBREG_REG (operands[0])) == REG
6905 && REGNO (SUBREG_REG (operands[0])) < 32))"
6906 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6907 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6908 "if (GET_CODE (operands[0]) == SUBREG)
6909 operands[0] = alter_subreg (operands[0]);
6910 operands[3] = gen_highpart (SImode, operands[0]);
6911 operands[4] = gen_highpart (SImode, operands[1]);
6912 operands[5] = gen_highpart (SImode, operands[2]);
6913 operands[6] = gen_lowpart (SImode, operands[0]);
6914 operands[7] = gen_lowpart (SImode, operands[1]);
6915 operands[8] = gen_lowpart (SImode, operands[2]);")
6917 (define_insn "*or_not_di_sp64"
6918 [(set (match_operand:DI 0 "register_operand" "=r,b")
6919 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6920 (match_operand:DI 2 "register_operand" "r,b")))]
6924 fornot1\\t%1, %2, %0"
6925 [(set_attr "type" "ialu,fp")
6926 (set_attr "length" "1,1")])
6928 (define_insn "*or_not_si"
6929 [(set (match_operand:SI 0 "register_operand" "=r,d")
6930 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6931 (match_operand:SI 2 "register_operand" "r,d")))]
6935 fornot1s\\t%1, %2, %0"
6936 [(set_attr "type" "ialu,fp")
6937 (set_attr "length" "1,1")])
6939 (define_expand "xordi3"
6940 [(set (match_operand:DI 0 "register_operand" "")
6941 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6942 (match_operand:DI 2 "arith_double_operand" "")))]
6946 (define_insn "*xordi3_sp32"
6947 [(set (match_operand:DI 0 "register_operand" "=r,b")
6948 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6949 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6954 [(set_attr "length" "2,1")
6955 (set_attr "type" "ialu,fp")])
6957 (define_insn "*xordi3_sp64"
6958 [(set (match_operand:DI 0 "register_operand" "=r,b")
6959 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6960 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6965 [(set_attr "type" "ialu,fp")
6966 (set_attr "length" "1,1")])
6968 (define_insn "*xordi3_sp64_dbl"
6969 [(set (match_operand:DI 0 "register_operand" "=r")
6970 (xor:DI (match_operand:DI 1 "register_operand" "r")
6971 (match_operand:DI 2 "const64_operand" "")))]
6973 && HOST_BITS_PER_WIDE_INT != 64)"
6975 [(set_attr "type" "ialu")
6976 (set_attr "length" "1")])
6978 (define_insn "xorsi3"
6979 [(set (match_operand:SI 0 "register_operand" "=r,d")
6980 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6981 (match_operand:SI 2 "arith_operand" "rI,d")))]
6986 [(set_attr "type" "ialu,fp")
6987 (set_attr "length" "1,1")])
6990 [(set (match_operand:SI 0 "register_operand" "")
6991 (xor:SI (match_operand:SI 1 "register_operand" "")
6992 (match_operand:SI 2 "" "")))
6993 (clobber (match_operand:SI 3 "register_operand" ""))]
6994 "GET_CODE (operands[2]) == CONST_INT
6995 && !SMALL_INT32 (operands[2])
6996 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6997 [(set (match_dup 3) (match_dup 4))
6998 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
7001 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
7005 [(set (match_operand:SI 0 "register_operand" "")
7006 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
7007 (match_operand:SI 2 "" ""))))
7008 (clobber (match_operand:SI 3 "register_operand" ""))]
7009 "GET_CODE (operands[2]) == CONST_INT
7010 && !SMALL_INT32 (operands[2])
7011 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
7012 [(set (match_dup 3) (match_dup 4))
7013 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
7016 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
7019 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
7020 ;; Combine now canonicalizes to the rightmost expression.
7021 (define_insn "*xor_not_di_sp32"
7022 [(set (match_operand:DI 0 "register_operand" "=r,b")
7023 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
7024 (match_operand:DI 2 "register_operand" "r,b"))))]
7029 [(set_attr "length" "2,1")
7030 (set_attr "type" "ialu,fp")])
7033 [(set (match_operand:DI 0 "register_operand" "")
7034 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
7035 (match_operand:DI 2 "register_operand" ""))))]
7038 && ((GET_CODE (operands[0]) == REG
7039 && REGNO (operands[0]) < 32)
7040 || (GET_CODE (operands[0]) == SUBREG
7041 && GET_CODE (SUBREG_REG (operands[0])) == REG
7042 && REGNO (SUBREG_REG (operands[0])) < 32))"
7043 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
7044 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
7045 "if (GET_CODE (operands[0]) == SUBREG)
7046 operands[0] = alter_subreg (operands[0]);
7047 operands[3] = gen_highpart (SImode, operands[0]);
7048 operands[4] = gen_highpart (SImode, operands[1]);
7049 operands[5] = gen_highpart (SImode, operands[2]);
7050 operands[6] = gen_lowpart (SImode, operands[0]);
7051 operands[7] = gen_lowpart (SImode, operands[1]);
7052 operands[8] = gen_lowpart (SImode, operands[2]);")
7054 (define_insn "*xor_not_di_sp64"
7055 [(set (match_operand:DI 0 "register_operand" "=r,b")
7056 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
7057 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
7062 [(set_attr "type" "ialu,fp")
7063 (set_attr "length" "1,1")])
7065 (define_insn "*xor_not_si"
7066 [(set (match_operand:SI 0 "register_operand" "=r,d")
7067 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
7068 (match_operand:SI 2 "arith_operand" "rI,d"))))]
7072 fxnors\\t%1, %2, %0"
7073 [(set_attr "type" "ialu,fp")
7074 (set_attr "length" "1,1")])
7076 ;; These correspond to the above in the case where we also (or only)
7077 ;; want to set the condition code.
7079 (define_insn "*cmp_cc_arith_op"
7082 (match_operator:SI 2 "cc_arithop"
7083 [(match_operand:SI 0 "arith_operand" "%r")
7084 (match_operand:SI 1 "arith_operand" "rI")])
7087 "%A2cc\\t%0, %1, %%g0"
7088 [(set_attr "type" "compare")
7089 (set_attr "length" "1")])
7091 (define_insn "*cmp_ccx_arith_op"
7094 (match_operator:DI 2 "cc_arithop"
7095 [(match_operand:DI 0 "arith_double_operand" "%r")
7096 (match_operand:DI 1 "arith_double_operand" "rHI")])
7099 "%A2cc\\t%0, %1, %%g0"
7100 [(set_attr "type" "compare")
7101 (set_attr "length" "1")])
7103 (define_insn "*cmp_cc_arith_op_set"
7106 (match_operator:SI 3 "cc_arithop"
7107 [(match_operand:SI 1 "arith_operand" "%r")
7108 (match_operand:SI 2 "arith_operand" "rI")])
7110 (set (match_operand:SI 0 "register_operand" "=r")
7113 "%A3cc\\t%1, %2, %0"
7114 [(set_attr "type" "compare")
7115 (set_attr "length" "1")])
7117 (define_insn "*cmp_ccx_arith_op_set"
7120 (match_operator:DI 3 "cc_arithop"
7121 [(match_operand:DI 1 "arith_double_operand" "%r")
7122 (match_operand:DI 2 "arith_double_operand" "rHI")])
7124 (set (match_operand:DI 0 "register_operand" "=r")
7127 "%A3cc\\t%1, %2, %0"
7128 [(set_attr "type" "compare")
7129 (set_attr "length" "1")])
7131 (define_insn "*cmp_cc_xor_not"
7134 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7135 (match_operand:SI 1 "arith_operand" "rI")))
7138 "xnorcc\\t%r0, %1, %%g0"
7139 [(set_attr "type" "compare")
7140 (set_attr "length" "1")])
7142 (define_insn "*cmp_ccx_xor_not"
7145 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7146 (match_operand:DI 1 "arith_double_operand" "rHI")))
7149 "xnorcc\\t%r0, %1, %%g0"
7150 [(set_attr "type" "compare")
7151 (set_attr "length" "1")])
7153 (define_insn "*cmp_cc_xor_not_set"
7156 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7157 (match_operand:SI 2 "arith_operand" "rI")))
7159 (set (match_operand:SI 0 "register_operand" "=r")
7160 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7162 "xnorcc\\t%r1, %2, %0"
7163 [(set_attr "type" "compare")
7164 (set_attr "length" "1")])
7166 (define_insn "*cmp_ccx_xor_not_set"
7169 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7170 (match_operand:DI 2 "arith_double_operand" "rHI")))
7172 (set (match_operand:DI 0 "register_operand" "=r")
7173 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7175 "xnorcc\\t%r1, %2, %0"
7176 [(set_attr "type" "compare")
7177 (set_attr "length" "1")])
7179 (define_insn "*cmp_cc_arith_op_not"
7182 (match_operator:SI 2 "cc_arithopn"
7183 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7184 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7187 "%B2cc\\t%r1, %0, %%g0"
7188 [(set_attr "type" "compare")
7189 (set_attr "length" "1")])
7191 (define_insn "*cmp_ccx_arith_op_not"
7194 (match_operator:DI 2 "cc_arithopn"
7195 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7196 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7199 "%B2cc\\t%r1, %0, %%g0"
7200 [(set_attr "type" "compare")
7201 (set_attr "length" "1")])
7203 (define_insn "*cmp_cc_arith_op_not_set"
7206 (match_operator:SI 3 "cc_arithopn"
7207 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7208 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7210 (set (match_operand:SI 0 "register_operand" "=r")
7213 "%B3cc\\t%r2, %1, %0"
7214 [(set_attr "type" "compare")
7215 (set_attr "length" "1")])
7217 (define_insn "*cmp_ccx_arith_op_not_set"
7220 (match_operator:DI 3 "cc_arithopn"
7221 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7222 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7224 (set (match_operand:DI 0 "register_operand" "=r")
7227 "%B3cc\\t%r2, %1, %0"
7228 [(set_attr "type" "compare")
7229 (set_attr "length" "1")])
7231 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7232 ;; does not know how to make it work for constants.
7234 (define_expand "negdi2"
7235 [(set (match_operand:DI 0 "register_operand" "=r")
7236 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7240 if (! TARGET_ARCH64)
7242 emit_insn (gen_rtx_PARALLEL
7245 gen_rtx_SET (VOIDmode, operand0,
7246 gen_rtx_NEG (DImode, operand1)),
7247 gen_rtx_CLOBBER (VOIDmode,
7248 gen_rtx_REG (CCmode,
7254 (define_insn "*negdi2_sp32"
7255 [(set (match_operand:DI 0 "register_operand" "=r")
7256 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7257 (clobber (reg:CC 100))]
7260 [(set_attr "type" "unary")
7261 (set_attr "length" "2")])
7264 [(set (match_operand:DI 0 "register_operand" "")
7265 (neg:DI (match_operand:DI 1 "register_operand" "")))
7266 (clobber (reg:CC 100))]
7268 && reload_completed"
7269 [(parallel [(set (reg:CC_NOOV 100)
7270 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7272 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7273 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7274 (ltu:SI (reg:CC 100) (const_int 0))))]
7275 "operands[2] = gen_highpart (SImode, operands[0]);
7276 operands[3] = gen_highpart (SImode, operands[1]);
7277 operands[4] = gen_lowpart (SImode, operands[0]);
7278 operands[5] = gen_lowpart (SImode, operands[1]);")
7280 (define_insn "*negdi2_sp64"
7281 [(set (match_operand:DI 0 "register_operand" "=r")
7282 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7284 "sub\\t%%g0, %1, %0"
7285 [(set_attr "type" "unary")
7286 (set_attr "length" "1")])
7288 (define_insn "negsi2"
7289 [(set (match_operand:SI 0 "register_operand" "=r")
7290 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7292 "sub\\t%%g0, %1, %0"
7293 [(set_attr "type" "unary")
7294 (set_attr "length" "1")])
7296 (define_insn "*cmp_cc_neg"
7297 [(set (reg:CC_NOOV 100)
7298 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7301 "subcc\\t%%g0, %0, %%g0"
7302 [(set_attr "type" "compare")
7303 (set_attr "length" "1")])
7305 (define_insn "*cmp_ccx_neg"
7306 [(set (reg:CCX_NOOV 100)
7307 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7310 "subcc\\t%%g0, %0, %%g0"
7311 [(set_attr "type" "compare")
7312 (set_attr "length" "1")])
7314 (define_insn "*cmp_cc_set_neg"
7315 [(set (reg:CC_NOOV 100)
7316 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7318 (set (match_operand:SI 0 "register_operand" "=r")
7319 (neg:SI (match_dup 1)))]
7321 "subcc\\t%%g0, %1, %0"
7322 [(set_attr "type" "compare")
7323 (set_attr "length" "1")])
7325 (define_insn "*cmp_ccx_set_neg"
7326 [(set (reg:CCX_NOOV 100)
7327 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7329 (set (match_operand:DI 0 "register_operand" "=r")
7330 (neg:DI (match_dup 1)))]
7332 "subcc\\t%%g0, %1, %0"
7333 [(set_attr "type" "compare")
7334 (set_attr "length" "1")])
7336 ;; We cannot use the "not" pseudo insn because the Sun assembler
7337 ;; does not know how to make it work for constants.
7338 (define_expand "one_cmpldi2"
7339 [(set (match_operand:DI 0 "register_operand" "")
7340 (not:DI (match_operand:DI 1 "register_operand" "")))]
7344 (define_insn "*one_cmpldi2_sp32"
7345 [(set (match_operand:DI 0 "register_operand" "=r,b")
7346 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7351 [(set_attr "type" "unary,fp")
7352 (set_attr "length" "2,1")])
7355 [(set (match_operand:DI 0 "register_operand" "")
7356 (not:DI (match_operand:DI 1 "register_operand" "")))]
7359 && ((GET_CODE (operands[0]) == REG
7360 && REGNO (operands[0]) < 32)
7361 || (GET_CODE (operands[0]) == SUBREG
7362 && GET_CODE (SUBREG_REG (operands[0])) == REG
7363 && REGNO (SUBREG_REG (operands[0])) < 32))"
7364 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7365 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7366 "if (GET_CODE (operands[0]) == SUBREG)
7367 operands[0] = alter_subreg (operands[0]);
7368 operands[2] = gen_highpart (SImode, operands[0]);
7369 operands[3] = gen_highpart (SImode, operands[1]);
7370 operands[4] = gen_lowpart (SImode, operands[0]);
7371 operands[5] = gen_lowpart (SImode, operands[1]);")
7373 (define_insn "*one_cmpldi2_sp64"
7374 [(set (match_operand:DI 0 "register_operand" "=r,b")
7375 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7380 [(set_attr "type" "unary,fp")
7381 (set_attr "length" "1")])
7383 (define_insn "one_cmplsi2"
7384 [(set (match_operand:SI 0 "register_operand" "=r,d")
7385 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7390 [(set_attr "type" "unary,fp")
7391 (set_attr "length" "1,1")])
7393 (define_insn "*cmp_cc_not"
7395 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7398 "xnorcc\\t%%g0, %0, %%g0"
7399 [(set_attr "type" "compare")
7400 (set_attr "length" "1")])
7402 (define_insn "*cmp_ccx_not"
7404 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7407 "xnorcc\\t%%g0, %0, %%g0"
7408 [(set_attr "type" "compare")
7409 (set_attr "length" "1")])
7411 (define_insn "*cmp_cc_set_not"
7413 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7415 (set (match_operand:SI 0 "register_operand" "=r")
7416 (not:SI (match_dup 1)))]
7418 "xnorcc\\t%%g0, %1, %0"
7419 [(set_attr "type" "compare")
7420 (set_attr "length" "1")])
7422 (define_insn "*cmp_ccx_set_not"
7424 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7426 (set (match_operand:DI 0 "register_operand" "=r")
7427 (not:DI (match_dup 1)))]
7429 "xnorcc\\t%%g0, %1, %0"
7430 [(set_attr "type" "compare")
7431 (set_attr "length" "1")])
7433 ;; Floating point arithmetic instructions.
7435 (define_expand "addtf3"
7436 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7437 (plus:TF (match_operand:TF 1 "general_operand" "")
7438 (match_operand:TF 2 "general_operand" "")))]
7439 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7442 if (! TARGET_HARD_QUAD)
7444 rtx slot0, slot1, slot2;
7446 if (GET_CODE (operands[0]) != MEM)
7447 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7449 slot0 = operands[0];
7450 if (GET_CODE (operands[1]) != MEM)
7452 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7453 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7456 slot1 = operands[1];
7457 if (GET_CODE (operands[2]) != MEM)
7459 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7460 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7463 slot2 = operands[2];
7465 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7467 XEXP (slot0, 0), Pmode,
7468 XEXP (slot1, 0), Pmode,
7469 XEXP (slot2, 0), Pmode);
7471 if (GET_CODE (operands[0]) != MEM)
7472 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7477 (define_insn "*addtf3_hq"
7478 [(set (match_operand:TF 0 "register_operand" "=e")
7479 (plus:TF (match_operand:TF 1 "register_operand" "e")
7480 (match_operand:TF 2 "register_operand" "e")))]
7481 "TARGET_FPU && TARGET_HARD_QUAD"
7482 "faddq\\t%1, %2, %0"
7483 [(set_attr "type" "fp")
7484 (set_attr "length" "1")])
7486 (define_insn "adddf3"
7487 [(set (match_operand:DF 0 "register_operand" "=e")
7488 (plus:DF (match_operand:DF 1 "register_operand" "e")
7489 (match_operand:DF 2 "register_operand" "e")))]
7491 "faddd\\t%1, %2, %0"
7492 [(set_attr "type" "fp")
7493 (set_attr "length" "1")])
7495 (define_insn "addsf3"
7496 [(set (match_operand:SF 0 "register_operand" "=f")
7497 (plus:SF (match_operand:SF 1 "register_operand" "f")
7498 (match_operand:SF 2 "register_operand" "f")))]
7500 "fadds\\t%1, %2, %0"
7501 [(set_attr "type" "fp")
7502 (set_attr "length" "1")])
7504 (define_expand "subtf3"
7505 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7506 (minus:TF (match_operand:TF 1 "general_operand" "")
7507 (match_operand:TF 2 "general_operand" "")))]
7508 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7511 if (! TARGET_HARD_QUAD)
7513 rtx slot0, slot1, slot2;
7515 if (GET_CODE (operands[0]) != MEM)
7516 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7518 slot0 = operands[0];
7519 if (GET_CODE (operands[1]) != MEM)
7521 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7522 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7525 slot1 = operands[1];
7526 if (GET_CODE (operands[2]) != MEM)
7528 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7529 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7532 slot2 = operands[2];
7534 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7536 XEXP (slot0, 0), Pmode,
7537 XEXP (slot1, 0), Pmode,
7538 XEXP (slot2, 0), Pmode);
7540 if (GET_CODE (operands[0]) != MEM)
7541 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7546 (define_insn "*subtf3_hq"
7547 [(set (match_operand:TF 0 "register_operand" "=e")
7548 (minus:TF (match_operand:TF 1 "register_operand" "e")
7549 (match_operand:TF 2 "register_operand" "e")))]
7550 "TARGET_FPU && TARGET_HARD_QUAD"
7551 "fsubq\\t%1, %2, %0"
7552 [(set_attr "type" "fp")
7553 (set_attr "length" "1")])
7555 (define_insn "subdf3"
7556 [(set (match_operand:DF 0 "register_operand" "=e")
7557 (minus:DF (match_operand:DF 1 "register_operand" "e")
7558 (match_operand:DF 2 "register_operand" "e")))]
7560 "fsubd\\t%1, %2, %0"
7561 [(set_attr "type" "fp")
7562 (set_attr "length" "1")])
7564 (define_insn "subsf3"
7565 [(set (match_operand:SF 0 "register_operand" "=f")
7566 (minus:SF (match_operand:SF 1 "register_operand" "f")
7567 (match_operand:SF 2 "register_operand" "f")))]
7569 "fsubs\\t%1, %2, %0"
7570 [(set_attr "type" "fp")
7571 (set_attr "length" "1")])
7573 (define_expand "multf3"
7574 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7575 (mult:TF (match_operand:TF 1 "general_operand" "")
7576 (match_operand:TF 2 "general_operand" "")))]
7577 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7580 if (! TARGET_HARD_QUAD)
7582 rtx slot0, slot1, slot2;
7584 if (GET_CODE (operands[0]) != MEM)
7585 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7587 slot0 = operands[0];
7588 if (GET_CODE (operands[1]) != MEM)
7590 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7591 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7594 slot1 = operands[1];
7595 if (GET_CODE (operands[2]) != MEM)
7597 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7598 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7601 slot2 = operands[2];
7603 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7605 XEXP (slot0, 0), Pmode,
7606 XEXP (slot1, 0), Pmode,
7607 XEXP (slot2, 0), Pmode);
7609 if (GET_CODE (operands[0]) != MEM)
7610 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7615 (define_insn "*multf3_hq"
7616 [(set (match_operand:TF 0 "register_operand" "=e")
7617 (mult:TF (match_operand:TF 1 "register_operand" "e")
7618 (match_operand:TF 2 "register_operand" "e")))]
7619 "TARGET_FPU && TARGET_HARD_QUAD"
7620 "fmulq\\t%1, %2, %0"
7621 [(set_attr "type" "fpmul")
7622 (set_attr "length" "1")])
7624 (define_insn "muldf3"
7625 [(set (match_operand:DF 0 "register_operand" "=e")
7626 (mult:DF (match_operand:DF 1 "register_operand" "e")
7627 (match_operand:DF 2 "register_operand" "e")))]
7629 "fmuld\\t%1, %2, %0"
7630 [(set_attr "type" "fpmul")
7631 (set_attr "length" "1")])
7633 (define_insn "mulsf3"
7634 [(set (match_operand:SF 0 "register_operand" "=f")
7635 (mult:SF (match_operand:SF 1 "register_operand" "f")
7636 (match_operand:SF 2 "register_operand" "f")))]
7638 "fmuls\\t%1, %2, %0"
7639 [(set_attr "type" "fpmul")
7640 (set_attr "length" "1")])
7642 (define_insn "*muldf3_extend"
7643 [(set (match_operand:DF 0 "register_operand" "=e")
7644 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7645 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7646 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7647 "fsmuld\\t%1, %2, %0"
7648 [(set_attr "type" "fpmul")
7649 (set_attr "length" "1")])
7651 (define_insn "*multf3_extend"
7652 [(set (match_operand:TF 0 "register_operand" "=e")
7653 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7654 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7655 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7656 "fdmulq\\t%1, %2, %0"
7657 [(set_attr "type" "fpmul")
7658 (set_attr "length" "1")])
7660 (define_expand "divtf3"
7661 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7662 (div:TF (match_operand:TF 1 "general_operand" "")
7663 (match_operand:TF 2 "general_operand" "")))]
7664 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7667 if (! TARGET_HARD_QUAD)
7669 rtx slot0, slot1, slot2;
7671 if (GET_CODE (operands[0]) != MEM)
7672 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7674 slot0 = operands[0];
7675 if (GET_CODE (operands[1]) != MEM)
7677 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7678 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7681 slot1 = operands[1];
7682 if (GET_CODE (operands[2]) != MEM)
7684 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7685 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7688 slot2 = operands[2];
7690 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7692 XEXP (slot0, 0), Pmode,
7693 XEXP (slot1, 0), Pmode,
7694 XEXP (slot2, 0), Pmode);
7696 if (GET_CODE (operands[0]) != MEM)
7697 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7702 ;; don't have timing for quad-prec. divide.
7703 (define_insn "*divtf3_hq"
7704 [(set (match_operand:TF 0 "register_operand" "=e")
7705 (div:TF (match_operand:TF 1 "register_operand" "e")
7706 (match_operand:TF 2 "register_operand" "e")))]
7707 "TARGET_FPU && TARGET_HARD_QUAD"
7708 "fdivq\\t%1, %2, %0"
7709 [(set_attr "type" "fpdivd")
7710 (set_attr "length" "1")])
7712 (define_insn "divdf3"
7713 [(set (match_operand:DF 0 "register_operand" "=e")
7714 (div:DF (match_operand:DF 1 "register_operand" "e")
7715 (match_operand:DF 2 "register_operand" "e")))]
7717 "fdivd\\t%1, %2, %0"
7718 [(set_attr "type" "fpdivd")
7719 (set_attr "length" "1")])
7721 (define_insn "divsf3"
7722 [(set (match_operand:SF 0 "register_operand" "=f")
7723 (div:SF (match_operand:SF 1 "register_operand" "f")
7724 (match_operand:SF 2 "register_operand" "f")))]
7726 "fdivs\\t%1, %2, %0"
7727 [(set_attr "type" "fpdivs")
7728 (set_attr "length" "1")])
7730 (define_expand "negtf2"
7731 [(set (match_operand:TF 0 "register_operand" "=e,e")
7732 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7736 (define_insn "*negtf2_notv9"
7737 [(set (match_operand:TF 0 "register_operand" "=e,e")
7738 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7739 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7745 [(set_attr "type" "fpmove")
7746 (set_attr "length" "1,2")])
7749 [(set (match_operand:TF 0 "register_operand" "")
7750 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7754 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7755 [(set (match_dup 2) (neg:SF (match_dup 3)))
7756 (set (match_dup 4) (match_dup 5))
7757 (set (match_dup 6) (match_dup 7))]
7758 "if (GET_CODE (operands[0]) == SUBREG)
7759 operands[0] = alter_subreg (operands[0]);
7760 if (GET_CODE (operands[1]) == SUBREG)
7761 operands[1] = alter_subreg (operands[1]);
7762 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7763 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7764 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7765 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7766 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7767 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7769 (define_insn "*negtf2_v9"
7770 [(set (match_operand:TF 0 "register_operand" "=e,e")
7771 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7772 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7773 "TARGET_FPU && TARGET_V9"
7777 [(set_attr "type" "fpmove")
7778 (set_attr "length" "1,2")])
7781 [(set (match_operand:TF 0 "register_operand" "")
7782 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7786 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7787 [(set (match_dup 2) (neg:DF (match_dup 3)))
7788 (set (match_dup 4) (match_dup 5))]
7789 "if (GET_CODE (operands[0]) == SUBREG)
7790 operands[0] = alter_subreg (operands[0]);
7791 if (GET_CODE (operands[1]) == SUBREG)
7792 operands[1] = alter_subreg (operands[1]);
7793 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7794 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7795 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7796 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7798 (define_expand "negdf2"
7799 [(set (match_operand:DF 0 "register_operand" "")
7800 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7804 (define_insn "*negdf2_notv9"
7805 [(set (match_operand:DF 0 "register_operand" "=e,e")
7806 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7807 "TARGET_FPU && ! TARGET_V9"
7811 [(set_attr "type" "fpmove")
7812 (set_attr "length" "1,2")])
7815 [(set (match_operand:DF 0 "register_operand" "")
7816 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7820 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7821 [(set (match_dup 2) (neg:SF (match_dup 3)))
7822 (set (match_dup 4) (match_dup 5))]
7823 "if (GET_CODE (operands[0]) == SUBREG)
7824 operands[0] = alter_subreg (operands[0]);
7825 if (GET_CODE (operands[1]) == SUBREG)
7826 operands[1] = alter_subreg (operands[1]);
7827 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7828 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7829 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7830 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7832 (define_insn "*negdf2_v9"
7833 [(set (match_operand:DF 0 "register_operand" "=e")
7834 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7835 "TARGET_FPU && TARGET_V9"
7837 [(set_attr "type" "fpmove")
7838 (set_attr "length" "1")])
7840 (define_insn "negsf2"
7841 [(set (match_operand:SF 0 "register_operand" "=f")
7842 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7845 [(set_attr "type" "fpmove")
7846 (set_attr "length" "1")])
7848 (define_expand "abstf2"
7849 [(set (match_operand:TF 0 "register_operand" "")
7850 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7854 (define_insn "*abstf2_notv9"
7855 [(set (match_operand:TF 0 "register_operand" "=e,e")
7856 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7857 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7858 "TARGET_FPU && ! TARGET_V9"
7862 [(set_attr "type" "fpmove")
7863 (set_attr "length" "1,2")])
7866 [(set (match_operand:TF 0 "register_operand" "=e,e")
7867 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7871 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7872 [(set (match_dup 2) (abs:SF (match_dup 3)))
7873 (set (match_dup 4) (match_dup 5))
7874 (set (match_dup 6) (match_dup 7))]
7875 "if (GET_CODE (operands[0]) == SUBREG)
7876 operands[0] = alter_subreg (operands[0]);
7877 if (GET_CODE (operands[1]) == SUBREG)
7878 operands[1] = alter_subreg (operands[1]);
7879 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7880 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7881 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7882 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7883 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7884 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7886 (define_insn "*abstf2_hq_v9"
7887 [(set (match_operand:TF 0 "register_operand" "=e,e")
7888 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7889 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7893 [(set_attr "type" "fpmove")
7894 (set_attr "length" "1")])
7896 (define_insn "*abstf2_v9"
7897 [(set (match_operand:TF 0 "register_operand" "=e,e")
7898 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7899 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7903 [(set_attr "type" "fpmove")
7904 (set_attr "length" "1,2")])
7907 [(set (match_operand:TF 0 "register_operand" "=e,e")
7908 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7912 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7913 [(set (match_dup 2) (abs:DF (match_dup 3)))
7914 (set (match_dup 4) (match_dup 5))]
7915 "if (GET_CODE (operands[0]) == SUBREG)
7916 operands[0] = alter_subreg (operands[0]);
7917 if (GET_CODE (operands[1]) == SUBREG)
7918 operands[1] = alter_subreg (operands[1]);
7919 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7920 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7921 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7922 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7924 (define_expand "absdf2"
7925 [(set (match_operand:DF 0 "register_operand" "")
7926 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7930 (define_insn "*absdf2_notv9"
7931 [(set (match_operand:DF 0 "register_operand" "=e,e")
7932 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7933 "TARGET_FPU && ! TARGET_V9"
7937 [(set_attr "type" "fpmove")
7938 (set_attr "length" "1,2")])
7941 [(set (match_operand:DF 0 "register_operand" "=e,e")
7942 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7946 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7947 [(set (match_dup 2) (abs:SF (match_dup 3)))
7948 (set (match_dup 4) (match_dup 5))]
7949 "if (GET_CODE (operands[0]) == SUBREG)
7950 operands[0] = alter_subreg (operands[0]);
7951 if (GET_CODE (operands[1]) == SUBREG)
7952 operands[1] = alter_subreg (operands[1]);
7953 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7954 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7955 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7956 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7958 (define_insn "*absdf2_v9"
7959 [(set (match_operand:DF 0 "register_operand" "=e")
7960 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7961 "TARGET_FPU && TARGET_V9"
7963 [(set_attr "type" "fpmove")
7964 (set_attr "length" "1")])
7966 (define_insn "abssf2"
7967 [(set (match_operand:SF 0 "register_operand" "=f")
7968 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7971 [(set_attr "type" "fpmove")
7972 (set_attr "length" "1")])
7974 (define_expand "sqrttf2"
7975 [(set (match_operand:TF 0 "register_operand" "=e")
7976 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7977 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7980 if (! TARGET_HARD_QUAD)
7984 if (GET_CODE (operands[0]) != MEM)
7985 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7987 slot0 = operands[0];
7988 if (GET_CODE (operands[1]) != MEM)
7990 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7991 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7994 slot1 = operands[1];
7996 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7998 XEXP (slot0, 0), Pmode,
7999 XEXP (slot1, 0), Pmode);
8001 if (GET_CODE (operands[0]) != MEM)
8002 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
8007 (define_insn "*sqrttf2_hq"
8008 [(set (match_operand:TF 0 "register_operand" "=e")
8009 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
8010 "TARGET_FPU && TARGET_HARD_QUAD"
8012 [(set_attr "type" "fpsqrtd")
8013 (set_attr "length" "1")])
8015 (define_insn "sqrtdf2"
8016 [(set (match_operand:DF 0 "register_operand" "=e")
8017 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
8020 [(set_attr "type" "fpsqrtd")
8021 (set_attr "length" "1")])
8023 (define_insn "sqrtsf2"
8024 [(set (match_operand:SF 0 "register_operand" "=f")
8025 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
8028 [(set_attr "type" "fpsqrts")
8029 (set_attr "length" "1")])
8031 ;;- arithmetic shift instructions
8033 (define_insn "ashlsi3"
8034 [(set (match_operand:SI 0 "register_operand" "=r")
8035 (ashift:SI (match_operand:SI 1 "register_operand" "r")
8036 (match_operand:SI 2 "arith_operand" "rI")))]
8040 if (GET_CODE (operands[2]) == CONST_INT
8041 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8042 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8044 return \"sll\\t%1, %2, %0\";
8046 [(set_attr "type" "shift")
8047 (set_attr "length" "1")])
8049 ;; We special case multiplication by two, as add can be done
8050 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8051 (define_insn "*ashlsi3_const1"
8052 [(set (match_operand:SI 0 "register_operand" "=r")
8053 (ashift:SI (match_operand:SI 1 "register_operand" "r")
8057 [(set_attr "type" "binary")
8058 (set_attr "length" "1")])
8060 (define_expand "ashldi3"
8061 [(set (match_operand:DI 0 "register_operand" "=r")
8062 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8063 (match_operand:SI 2 "arith_operand" "rI")))]
8064 "TARGET_ARCH64 || TARGET_V8PLUS"
8067 if (! TARGET_ARCH64)
8069 if (GET_CODE (operands[2]) == CONST_INT)
8071 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
8076 ;; We special case multiplication by two, as add can be done
8077 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8078 (define_insn "*ashldi3_const1"
8079 [(set (match_operand:DI 0 "register_operand" "=r")
8080 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8084 [(set_attr "type" "binary")
8085 (set_attr "length" "1")])
8087 (define_insn "*ashldi3_sp64"
8088 [(set (match_operand:DI 0 "register_operand" "=r")
8089 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8090 (match_operand:SI 2 "arith_operand" "rI")))]
8094 if (GET_CODE (operands[2]) == CONST_INT
8095 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8096 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8098 return \"sllx\\t%1, %2, %0\";
8100 [(set_attr "type" "shift")
8101 (set_attr "length" "1")])
8104 (define_insn "ashldi3_v8plus"
8105 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8106 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8107 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8108 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8110 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
8111 [(set_attr "length" "5,5,6")])
8113 ;; Optimize (1LL<<x)-1
8114 ;; XXX this also needs to be fixed to handle equal subregs
8115 ;; XXX first before we could re-enable it.
8117 ; [(set (match_operand:DI 0 "register_operand" "=h")
8118 ; (plus:DI (ashift:DI (const_int 1)
8119 ; (match_operand:SI 1 "arith_operand" "rI"))
8121 ; "0 && TARGET_V8PLUS"
8124 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
8125 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8126 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8128 ; [(set_attr "length" "4")])
8130 (define_insn "*cmp_cc_ashift_1"
8131 [(set (reg:CC_NOOV 100)
8132 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8136 "addcc\\t%0, %0, %%g0"
8137 [(set_attr "type" "compare")
8138 (set_attr "length" "1")])
8140 (define_insn "*cmp_cc_set_ashift_1"
8141 [(set (reg:CC_NOOV 100)
8142 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8145 (set (match_operand:SI 0 "register_operand" "=r")
8146 (ashift:SI (match_dup 1) (const_int 1)))]
8148 "addcc\\t%1, %1, %0"
8149 [(set_attr "type" "compare")
8150 (set_attr "length" "1")])
8152 (define_insn "ashrsi3"
8153 [(set (match_operand:SI 0 "register_operand" "=r")
8154 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8155 (match_operand:SI 2 "arith_operand" "rI")))]
8159 if (GET_CODE (operands[2]) == CONST_INT
8160 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8161 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8163 return \"sra\\t%1, %2, %0\";
8165 [(set_attr "type" "shift")
8166 (set_attr "length" "1")])
8168 (define_insn "*ashrsi3_extend"
8169 [(set (match_operand:DI 0 "register_operand" "=r")
8170 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8171 (match_operand:SI 2 "arith_operand" "r"))))]
8174 [(set_attr "type" "shift")
8175 (set_attr "length" "1")])
8177 ;; This handles the case as above, but with constant shift instead of
8178 ;; register. Combiner "simplifies" it for us a little bit though.
8179 (define_insn "*ashrsi3_extend2"
8180 [(set (match_operand:DI 0 "register_operand" "=r")
8181 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8183 (match_operand:SI 2 "small_int_or_double" "n")))]
8185 && ((GET_CODE (operands[2]) == CONST_INT
8186 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8187 || (GET_CODE (operands[2]) == CONST_DOUBLE
8188 && !CONST_DOUBLE_HIGH (operands[2])
8189 && CONST_DOUBLE_LOW (operands[2]) >= 32
8190 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8193 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8195 return \"sra\\t%1, %2, %0\";
8197 [(set_attr "type" "shift")
8198 (set_attr "length" "1")])
8200 (define_expand "ashrdi3"
8201 [(set (match_operand:DI 0 "register_operand" "=r")
8202 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8203 (match_operand:SI 2 "arith_operand" "rI")))]
8204 "TARGET_ARCH64 || TARGET_V8PLUS"
8207 if (! TARGET_ARCH64)
8209 if (GET_CODE (operands[2]) == CONST_INT)
8210 FAIL; /* prefer generic code in this case */
8211 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8217 [(set (match_operand:DI 0 "register_operand" "=r")
8218 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8219 (match_operand:SI 2 "arith_operand" "rI")))]
8223 if (GET_CODE (operands[2]) == CONST_INT
8224 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8225 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8227 return \"srax\\t%1, %2, %0\";
8229 [(set_attr "type" "shift")
8230 (set_attr "length" "1")])
8233 (define_insn "ashrdi3_v8plus"
8234 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8235 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8236 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8237 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8239 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8240 [(set_attr "length" "5,5,6")])
8242 (define_insn "lshrsi3"
8243 [(set (match_operand:SI 0 "register_operand" "=r")
8244 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8245 (match_operand:SI 2 "arith_operand" "rI")))]
8249 if (GET_CODE (operands[2]) == CONST_INT
8250 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8251 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8253 return \"srl\\t%1, %2, %0\";
8255 [(set_attr "type" "shift")
8256 (set_attr "length" "1")])
8258 ;; This handles the case where
8259 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8260 ;; but combiner "simplifies" it for us.
8261 (define_insn "*lshrsi3_extend"
8262 [(set (match_operand:DI 0 "register_operand" "=r")
8263 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8264 (match_operand:SI 2 "arith_operand" "r")) 0)
8265 (match_operand 3 "" "")))]
8267 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8268 && CONST_DOUBLE_HIGH (operands[3]) == 0
8269 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8270 #if HOST_BITS_PER_WIDE_INT >= 64
8271 || (GET_CODE (operands[3]) == CONST_INT
8272 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff)
8276 [(set_attr "type" "shift")
8277 (set_attr "length" "1")])
8279 ;; This handles the case where
8280 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8281 ;; but combiner "simplifies" it for us.
8282 (define_insn "*lshrsi3_extend2"
8283 [(set (match_operand:DI 0 "register_operand" "=r")
8284 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8285 (match_operand 2 "small_int_or_double" "n")
8288 && ((GET_CODE (operands[2]) == CONST_INT
8289 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8290 || (GET_CODE (operands[2]) == CONST_DOUBLE
8291 && CONST_DOUBLE_HIGH (operands[2]) == 0
8292 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8295 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8297 return \"srl\\t%1, %2, %0\";
8299 [(set_attr "type" "shift")
8300 (set_attr "length" "1")])
8302 (define_expand "lshrdi3"
8303 [(set (match_operand:DI 0 "register_operand" "=r")
8304 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8305 (match_operand:SI 2 "arith_operand" "rI")))]
8306 "TARGET_ARCH64 || TARGET_V8PLUS"
8309 if (! TARGET_ARCH64)
8311 if (GET_CODE (operands[2]) == CONST_INT)
8313 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8319 [(set (match_operand:DI 0 "register_operand" "=r")
8320 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8321 (match_operand:SI 2 "arith_operand" "rI")))]
8325 if (GET_CODE (operands[2]) == CONST_INT
8326 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8327 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8329 return \"srlx\\t%1, %2, %0\";
8331 [(set_attr "type" "shift")
8332 (set_attr "length" "1")])
8335 (define_insn "lshrdi3_v8plus"
8336 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8337 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8338 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8339 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8341 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8342 [(set_attr "length" "5,5,6")])
8345 [(set (match_operand:SI 0 "register_operand" "=r")
8346 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8348 (match_operand:SI 2 "small_int_or_double" "n")))]
8350 && ((GET_CODE (operands[2]) == CONST_INT
8351 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8352 || (GET_CODE (operands[2]) == CONST_DOUBLE
8353 && !CONST_DOUBLE_HIGH (operands[2])
8354 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8357 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8359 return \"srax\\t%1, %2, %0\";
8361 [(set_attr "type" "shift")
8362 (set_attr "length" "1")])
8365 [(set (match_operand:SI 0 "register_operand" "=r")
8366 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8368 (match_operand:SI 2 "small_int_or_double" "n")))]
8370 && ((GET_CODE (operands[2]) == CONST_INT
8371 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8372 || (GET_CODE (operands[2]) == CONST_DOUBLE
8373 && !CONST_DOUBLE_HIGH (operands[2])
8374 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8377 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8379 return \"srlx\\t%1, %2, %0\";
8381 [(set_attr "type" "shift")
8382 (set_attr "length" "1")])
8385 [(set (match_operand:SI 0 "register_operand" "=r")
8386 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8387 (match_operand:SI 2 "small_int_or_double" "n")) 0)
8388 (match_operand:SI 3 "small_int_or_double" "n")))]
8390 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8391 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8392 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8393 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8396 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8398 return \"srax\\t%1, %2, %0\";
8400 [(set_attr "type" "shift")
8401 (set_attr "length" "1")])
8404 [(set (match_operand:SI 0 "register_operand" "=r")
8405 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8406 (match_operand:SI 2 "small_int_or_double" "n")) 0)
8407 (match_operand:SI 3 "small_int_or_double" "n")))]
8409 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8410 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8411 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8412 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8415 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8417 return \"srlx\\t%1, %2, %0\";
8419 [(set_attr "type" "shift")
8420 (set_attr "length" "1")])
8422 ;; Unconditional and other jump instructions
8423 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8424 ;; following insn is never executed. This saves us a nop. Dbx does not
8425 ;; handle such branches though, so we only use them when optimizing.
8427 [(set (pc) (label_ref (match_operand 0 "" "")))]
8431 /* TurboSparc is reported to have problems with
8434 i.e. an empty loop with the annul bit set. The workaround is to use
8438 if (! TARGET_V9 && flag_delayed_branch
8439 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8440 == INSN_ADDRESSES (INSN_UID (insn))))
8441 return \"b\\t%l0%#\";
8443 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8445 [(set_attr "type" "uncond_branch")])
8447 (define_expand "tablejump"
8448 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8449 (use (label_ref (match_operand 1 "" "")))])]
8453 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8456 /* In pic mode, our address differences are against the base of the
8457 table. Add that base value back in; CSE ought to be able to combine
8458 the two address loads. */
8462 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8464 if (CASE_VECTOR_MODE != Pmode)
8465 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8466 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8467 operands[0] = memory_address (Pmode, tmp);
8471 (define_insn "*tablejump_sp32"
8472 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8473 (use (label_ref (match_operand 1 "" "")))]
8476 [(set_attr "type" "uncond_branch")])
8478 (define_insn "*tablejump_sp64"
8479 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8480 (use (label_ref (match_operand 1 "" "")))]
8483 [(set_attr "type" "uncond_branch")])
8485 ;; This pattern recognizes the "instruction" that appears in
8486 ;; a function call that wants a structure value,
8487 ;; to inform the called function if compiled with Sun CC.
8488 ;(define_insn "*unimp_insn"
8489 ; [(match_operand:SI 0 "immediate_operand" "")]
8490 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8492 ; [(set_attr "type" "marker")])
8494 ;;- jump to subroutine
8495 (define_expand "call"
8496 ;; Note that this expression is not used for generating RTL.
8497 ;; All the RTL is generated explicitly below.
8498 [(call (match_operand 0 "call_operand" "")
8499 (match_operand 3 "" "i"))]
8500 ;; operands[2] is next_arg_register
8501 ;; operands[3] is struct_value_size_rtx.
8505 rtx fn_rtx, nregs_rtx;
8507 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8510 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8512 /* This is really a PIC sequence. We want to represent
8513 it as a funny jump so its delay slots can be filled.
8515 ??? But if this really *is* a CALL, will not it clobber the
8516 call-clobbered registers? We lose this if it is a JUMP_INSN.
8517 Why cannot we have delay slots filled if it were a CALL? */
8519 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8524 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8526 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8532 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8533 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8537 fn_rtx = operands[0];
8539 /* Count the number of parameter registers being used by this call.
8540 if that argument is NULL, it means we are using them all, which
8541 means 6 on the sparc. */
8544 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8546 nregs_rtx = GEN_INT (6);
8548 nregs_rtx = const0_rtx;
8551 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8555 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8557 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8562 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8563 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8567 /* If this call wants a structure value,
8568 emit an unimp insn to let the called function know about this. */
8569 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8571 rtx insn = emit_insn (operands[3]);
8572 SCHED_GROUP_P (insn) = 1;
8579 ;; We can't use the same pattern for these two insns, because then registers
8580 ;; in the address may not be properly reloaded.
8582 (define_insn "*call_address_sp32"
8583 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8584 (match_operand 1 "" ""))
8585 (clobber (reg:SI 15))]
8586 ;;- Do not use operand 1 for most machines.
8589 [(set_attr "type" "call")])
8591 (define_insn "*call_symbolic_sp32"
8592 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8593 (match_operand 1 "" ""))
8594 (clobber (reg:SI 15))]
8595 ;;- Do not use operand 1 for most machines.
8598 [(set_attr "type" "call")])
8600 (define_insn "*call_address_sp64"
8601 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8602 (match_operand 1 "" ""))
8603 (clobber (reg:DI 15))]
8604 ;;- Do not use operand 1 for most machines.
8607 [(set_attr "type" "call")])
8609 (define_insn "*call_symbolic_sp64"
8610 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8611 (match_operand 1 "" ""))
8612 (clobber (reg:DI 15))]
8613 ;;- Do not use operand 1 for most machines.
8616 [(set_attr "type" "call")])
8618 ;; This is a call that wants a structure value.
8619 ;; There is no such critter for v9 (??? we may need one anyway).
8620 (define_insn "*call_address_struct_value_sp32"
8621 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8622 (match_operand 1 "" ""))
8623 (match_operand 2 "immediate_operand" "")
8624 (clobber (reg:SI 15))]
8625 ;;- Do not use operand 1 for most machines.
8626 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8627 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8628 [(set_attr "type" "call_no_delay_slot")])
8630 ;; This is a call that wants a structure value.
8631 ;; There is no such critter for v9 (??? we may need one anyway).
8632 (define_insn "*call_symbolic_struct_value_sp32"
8633 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8634 (match_operand 1 "" ""))
8635 (match_operand 2 "immediate_operand" "")
8636 (clobber (reg:SI 15))]
8637 ;;- Do not use operand 1 for most machines.
8638 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8639 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8640 [(set_attr "type" "call_no_delay_slot")])
8642 ;; This is a call that may want a structure value. This is used for
8644 (define_insn "*call_address_untyped_struct_value_sp32"
8645 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8646 (match_operand 1 "" ""))
8647 (match_operand 2 "immediate_operand" "")
8648 (clobber (reg:SI 15))]
8649 ;;- Do not use operand 1 for most machines.
8650 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8651 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8652 [(set_attr "type" "call_no_delay_slot")])
8654 ;; This is a call that wants a structure value.
8655 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8656 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8657 (match_operand 1 "" ""))
8658 (match_operand 2 "immediate_operand" "")
8659 (clobber (reg:SI 15))]
8660 ;;- Do not use operand 1 for most machines.
8661 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8662 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8663 [(set_attr "type" "call_no_delay_slot")])
8665 (define_expand "call_value"
8666 ;; Note that this expression is not used for generating RTL.
8667 ;; All the RTL is generated explicitly below.
8668 [(set (match_operand 0 "register_operand" "=rf")
8669 (call (match_operand 1 "" "")
8670 (match_operand 4 "" "")))]
8671 ;; operand 2 is stack_size_rtx
8672 ;; operand 3 is next_arg_register
8676 rtx fn_rtx, nregs_rtx;
8679 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8682 fn_rtx = operands[1];
8686 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8688 nregs_rtx = GEN_INT (6);
8690 nregs_rtx = const0_rtx;
8694 gen_rtx_SET (VOIDmode, operands[0],
8695 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8696 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8698 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8703 (define_insn "*call_value_address_sp32"
8704 [(set (match_operand 0 "" "=rf")
8705 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8706 (match_operand 2 "" "")))
8707 (clobber (reg:SI 15))]
8708 ;;- Do not use operand 2 for most machines.
8711 [(set_attr "type" "call")])
8713 (define_insn "*call_value_symbolic_sp32"
8714 [(set (match_operand 0 "" "=rf")
8715 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8716 (match_operand 2 "" "")))
8717 (clobber (reg:SI 15))]
8718 ;;- Do not use operand 2 for most machines.
8721 [(set_attr "type" "call")])
8723 (define_insn "*call_value_address_sp64"
8724 [(set (match_operand 0 "" "")
8725 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8726 (match_operand 2 "" "")))
8727 (clobber (reg:DI 15))]
8728 ;;- Do not use operand 2 for most machines.
8731 [(set_attr "type" "call")])
8733 (define_insn "*call_value_symbolic_sp64"
8734 [(set (match_operand 0 "" "")
8735 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8736 (match_operand 2 "" "")))
8737 (clobber (reg:DI 15))]
8738 ;;- Do not use operand 2 for most machines.
8741 [(set_attr "type" "call")])
8743 (define_expand "untyped_call"
8744 [(parallel [(call (match_operand 0 "" "")
8746 (match_operand 1 "" "")
8747 (match_operand 2 "" "")])]
8753 /* Pass constm1 to indicate that it may expect a structure value, but
8754 we don't know what size it is. */
8755 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8757 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8759 rtx set = XVECEXP (operands[2], 0, i);
8760 emit_move_insn (SET_DEST (set), SET_SRC (set));
8763 /* The optimizer does not know that the call sets the function value
8764 registers we stored in the result block. We avoid problems by
8765 claiming that all hard registers are used and clobbered at this
8767 emit_insn (gen_blockage ());
8773 (define_expand "sibcall"
8774 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8779 (define_insn "*sibcall_symbolic_sp32"
8780 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8781 (match_operand 1 "" ""))
8784 "* return output_sibcall(insn, operands[0]);"
8785 [(set_attr "type" "sibcall")])
8787 (define_insn "*sibcall_symbolic_sp64"
8788 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8789 (match_operand 1 "" ""))
8792 "* return output_sibcall(insn, operands[0]);"
8793 [(set_attr "type" "sibcall")])
8795 (define_expand "sibcall_value"
8796 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8797 (call (match_operand 1 "" "") (const_int 0)))
8802 (define_insn "*sibcall_value_symbolic_sp32"
8803 [(set (match_operand 0 "" "=rf")
8804 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8805 (match_operand 2 "" "")))
8808 "* return output_sibcall(insn, operands[1]);"
8809 [(set_attr "type" "sibcall")])
8811 (define_insn "*sibcall_value_symbolic_sp64"
8812 [(set (match_operand 0 "" "")
8813 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8814 (match_operand 2 "" "")))
8817 "* return output_sibcall(insn, operands[1]);"
8818 [(set_attr "type" "sibcall")])
8820 (define_expand "sibcall_epilogue"
8825 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8826 ;; all of memory. This blocks insns from being moved across this point.
8828 (define_insn "blockage"
8829 [(unspec_volatile [(const_int 0)] 0)]
8832 [(set_attr "length" "0")])
8834 ;; Prepare to return any type including a structure value.
8836 (define_expand "untyped_return"
8837 [(match_operand:BLK 0 "memory_operand" "")
8838 (match_operand 1 "" "")]
8842 rtx valreg1 = gen_rtx_REG (DImode, 24);
8843 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8844 rtx result = operands[0];
8846 if (! TARGET_ARCH64)
8848 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8850 rtx value = gen_reg_rtx (SImode);
8852 /* Fetch the instruction where we will return to and see if it's an unimp
8853 instruction (the most significant 10 bits will be zero). If so,
8854 update the return address to skip the unimp instruction. */
8855 emit_move_insn (value,
8856 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8857 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8858 emit_insn (gen_update_return (rtnreg, value));
8861 /* Reload the function value registers. */
8862 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
8863 emit_move_insn (valreg2,
8864 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
8865 plus_constant (XEXP (result, 0), 8)));
8867 /* Put USE insns before the return. */
8868 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8869 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8871 /* Construct the return. */
8872 expand_null_return ();
8877 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8878 ;; and parts of the compiler don't want to believe that the add is needed.
8880 (define_insn "update_return"
8881 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8882 (match_operand:SI 1 "register_operand" "r")] 1)]
8884 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8885 [(set_attr "type" "multi")])
8887 (define_insn "return"
8891 "* return output_return (operands);"
8892 [(set_attr "type" "return")])
8895 [(set (match_operand:SI 0 "register_operand" "=r")
8896 (match_operand:SI 1 "arith_operand" "rI"))
8898 (use (reg:SI 31))])]
8899 "sparc_return_peephole_ok (operands[0], operands[1])"
8900 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8906 [(set_attr "type" "ialu")
8907 (set_attr "length" "1")])
8909 (define_expand "indirect_jump"
8910 [(set (pc) (match_operand 0 "address_operand" "p"))]
8914 (define_insn "*branch_sp32"
8915 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8918 [(set_attr "type" "uncond_branch")])
8920 (define_insn "*branch_sp64"
8921 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8924 [(set_attr "type" "uncond_branch")])
8926 ;; ??? Doesn't work with -mflat.
8927 (define_expand "nonlocal_goto"
8928 [(match_operand:SI 0 "general_operand" "")
8929 (match_operand:SI 1 "general_operand" "")
8930 (match_operand:SI 2 "general_operand" "")
8931 (match_operand:SI 3 "" "")]
8936 rtx chain = operands[0];
8938 rtx fp = operands[1];
8939 rtx stack = operands[2];
8940 rtx lab = operands[3];
8943 /* Trap instruction to flush all the register windows. */
8944 emit_insn (gen_flush_register_windows ());
8946 /* Load the fp value for the containing fn into %fp. This is needed
8947 because STACK refers to %fp. Note that virtual register instantiation
8948 fails if the virtual %fp isn't set from a register. */
8949 if (GET_CODE (fp) != REG)
8950 fp = force_reg (Pmode, fp);
8951 emit_move_insn (virtual_stack_vars_rtx, fp);
8953 /* Find the containing function's current nonlocal goto handler,
8954 which will do any cleanups and then jump to the label. */
8955 labreg = gen_rtx_REG (Pmode, 8);
8956 emit_move_insn (labreg, lab);
8958 /* Restore %fp from stack pointer value for containing function.
8959 The restore insn that follows will move this to %sp,
8960 and reload the appropriate value into %fp. */
8961 emit_move_insn (frame_pointer_rtx, stack);
8963 /* USE of frame_pointer_rtx added for consistency; not clear if
8965 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8966 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8969 /* Return, restoring reg window and jumping to goto handler. */
8970 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8971 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8973 emit_insn (gen_goto_handler_and_restore_v9 (labreg, static_chain_rtx,
8978 /* Put in the static chain register the nonlocal label address. */
8979 emit_move_insn (static_chain_rtx, chain);
8982 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8983 emit_insn (gen_goto_handler_and_restore (labreg));
8988 ;; Special trap insn to flush register windows.
8989 (define_insn "flush_register_windows"
8990 [(unspec_volatile [(const_int 0)] 1)]
8992 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8993 [(set_attr "type" "misc")
8994 (set_attr "length" "1")])
8996 (define_insn "goto_handler_and_restore"
8997 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8998 "GET_MODE (operands[0]) == Pmode"
8999 "jmp\\t%0+0\\n\\trestore"
9000 [(set_attr "type" "misc")
9001 (set_attr "length" "2")])
9003 ;;(define_insn "goto_handler_and_restore_v9"
9004 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
9005 ;; (match_operand:SI 1 "register_operand" "=r,r")
9006 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
9007 ;; "TARGET_V9 && ! TARGET_ARCH64"
9009 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
9010 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
9011 ;; [(set_attr "type" "misc")
9012 ;; (set_attr "length" "2,3")])
9014 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
9015 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
9016 ;; (match_operand:DI 1 "register_operand" "=r,r")
9017 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
9018 ;; "TARGET_V9 && TARGET_ARCH64"
9020 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
9021 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
9022 ;; [(set_attr "type" "misc")
9023 ;; (set_attr "length" "2,3")])
9025 ;; For __builtin_setjmp we need to flush register windows iff the function
9026 ;; calls alloca as well, because otherwise the register window might be
9027 ;; saved after %sp adjustement and thus setjmp would crash
9028 (define_expand "builtin_setjmp_setup"
9029 [(match_operand 0 "register_operand" "r")]
9033 emit_insn (gen_do_builtin_setjmp_setup ());
9037 (define_insn "do_builtin_setjmp_setup"
9038 [(unspec_volatile [(const_int 0)] 5)]
9042 if (!current_function_calls_alloca)
9048 [(set_attr "type" "misc")
9049 (set_attr "length" "1")])
9051 ;; Pattern for use after a setjmp to store FP and the return register
9052 ;; into the stack area.
9054 (define_expand "setjmp"
9060 emit_insn (gen_setjmp_64 ());
9062 emit_insn (gen_setjmp_32 ());
9066 (define_expand "setjmp_32"
9067 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
9068 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
9071 { operands[0] = frame_pointer_rtx; }")
9073 (define_expand "setjmp_64"
9074 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
9075 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
9078 { operands[0] = frame_pointer_rtx; }")
9080 ;; Special pattern for the FLUSH instruction.
9082 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
9083 ; of the define_insn otherwise missing a mode. We make "flush", aka
9084 ; gen_flush, the default one since sparc_initialize_trampoline uses
9085 ; it on SImode mem values.
9087 (define_insn "flush"
9088 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
9090 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
9091 [(set_attr "type" "misc")])
9093 (define_insn "flushdi"
9094 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
9096 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
9097 [(set_attr "type" "misc")])
9102 ;; The scan instruction searches from the most significant bit while ffs
9103 ;; searches from the least significant bit. The bit index and treatment of
9104 ;; zero also differ. It takes at least 7 instructions to get the proper
9105 ;; result. Here is an obvious 8 instruction sequence.
9108 (define_insn "ffssi2"
9109 [(set (match_operand:SI 0 "register_operand" "=&r")
9110 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
9111 (clobber (match_scratch:SI 2 "=&r"))]
9112 "TARGET_SPARCLITE || TARGET_SPARCLET"
9115 return \"sub\\t%%g0, %1, %0\;and\\t%0, %1, %0\;scan\\t%0, 0, %0\;mov\\t32, %2\;sub\\t%2, %0, %0\;sra\\t%0, 31, %2\;and\\t%2, 31, %2\;add\\t%2, %0, %0\";
9117 [(set_attr "type" "multi")
9118 (set_attr "length" "8")])
9120 ;; ??? This should be a define expand, so that the extra instruction have
9121 ;; a chance of being optimized away.
9123 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
9124 ;; does, but no one uses that and we don't have a switch for it.
9126 ;(define_insn "ffsdi2"
9127 ; [(set (match_operand:DI 0 "register_operand" "=&r")
9128 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
9129 ; (clobber (match_scratch:DI 2 "=&r"))]
9131 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
9132 ; [(set_attr "type" "multi")
9133 ; (set_attr "length" "4")])
9137 ;; Peepholes go at the end.
9139 ;; Optimize consecutive loads or stores into ldd and std when possible.
9140 ;; The conditions in which we do this are very restricted and are
9141 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
9144 [(set (match_operand:SI 0 "memory_operand" "")
9146 (set (match_operand:SI 1 "memory_operand" "")
9149 && ! MEM_VOLATILE_P (operands[0])
9150 && ! MEM_VOLATILE_P (operands[1])
9151 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
9155 [(set (match_operand:SI 0 "memory_operand" "")
9157 (set (match_operand:SI 1 "memory_operand" "")
9160 && ! MEM_VOLATILE_P (operands[0])
9161 && ! MEM_VOLATILE_P (operands[1])
9162 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
9166 [(set (match_operand:SI 0 "register_operand" "=rf")
9167 (match_operand:SI 1 "memory_operand" ""))
9168 (set (match_operand:SI 2 "register_operand" "=rf")
9169 (match_operand:SI 3 "memory_operand" ""))]
9170 "registers_ok_for_ldd_peep (operands[0], operands[2])
9171 && ! MEM_VOLATILE_P (operands[1])
9172 && ! MEM_VOLATILE_P (operands[3])
9173 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9177 [(set (match_operand:SI 0 "memory_operand" "")
9178 (match_operand:SI 1 "register_operand" "rf"))
9179 (set (match_operand:SI 2 "memory_operand" "")
9180 (match_operand:SI 3 "register_operand" "rf"))]
9181 "registers_ok_for_ldd_peep (operands[1], operands[3])
9182 && ! MEM_VOLATILE_P (operands[0])
9183 && ! MEM_VOLATILE_P (operands[2])
9184 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9188 [(set (match_operand:SF 0 "register_operand" "=fr")
9189 (match_operand:SF 1 "memory_operand" ""))
9190 (set (match_operand:SF 2 "register_operand" "=fr")
9191 (match_operand:SF 3 "memory_operand" ""))]
9192 "registers_ok_for_ldd_peep (operands[0], operands[2])
9193 && ! MEM_VOLATILE_P (operands[1])
9194 && ! MEM_VOLATILE_P (operands[3])
9195 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9199 [(set (match_operand:SF 0 "memory_operand" "")
9200 (match_operand:SF 1 "register_operand" "fr"))
9201 (set (match_operand:SF 2 "memory_operand" "")
9202 (match_operand:SF 3 "register_operand" "fr"))]
9203 "registers_ok_for_ldd_peep (operands[1], operands[3])
9204 && ! MEM_VOLATILE_P (operands[0])
9205 && ! MEM_VOLATILE_P (operands[2])
9206 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9210 [(set (match_operand:SI 0 "register_operand" "=rf")
9211 (match_operand:SI 1 "memory_operand" ""))
9212 (set (match_operand:SI 2 "register_operand" "=rf")
9213 (match_operand:SI 3 "memory_operand" ""))]
9214 "registers_ok_for_ldd_peep (operands[2], operands[0])
9215 && ! MEM_VOLATILE_P (operands[3])
9216 && ! MEM_VOLATILE_P (operands[1])
9217 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9221 [(set (match_operand:SI 0 "memory_operand" "")
9222 (match_operand:SI 1 "register_operand" "rf"))
9223 (set (match_operand:SI 2 "memory_operand" "")
9224 (match_operand:SI 3 "register_operand" "rf"))]
9225 "registers_ok_for_ldd_peep (operands[3], operands[1])
9226 && ! MEM_VOLATILE_P (operands[2])
9227 && ! MEM_VOLATILE_P (operands[0])
9228 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9232 [(set (match_operand:SF 0 "register_operand" "=fr")
9233 (match_operand:SF 1 "memory_operand" ""))
9234 (set (match_operand:SF 2 "register_operand" "=fr")
9235 (match_operand:SF 3 "memory_operand" ""))]
9236 "registers_ok_for_ldd_peep (operands[2], operands[0])
9237 && ! MEM_VOLATILE_P (operands[3])
9238 && ! MEM_VOLATILE_P (operands[1])
9239 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9243 [(set (match_operand:SF 0 "memory_operand" "")
9244 (match_operand:SF 1 "register_operand" "fr"))
9245 (set (match_operand:SF 2 "memory_operand" "")
9246 (match_operand:SF 3 "register_operand" "fr"))]
9247 "registers_ok_for_ldd_peep (operands[3], operands[1])
9248 && ! MEM_VOLATILE_P (operands[2])
9249 && ! MEM_VOLATILE_P (operands[0])
9250 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9253 ;; Optimize the case of following a reg-reg move with a test
9254 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9255 ;; This can result from a float to fix conversion.
9258 [(set (match_operand:SI 0 "register_operand" "=r")
9259 (match_operand:SI 1 "register_operand" "r"))
9261 (compare:CC (match_operand:SI 2 "register_operand" "r")
9263 "(rtx_equal_p (operands[2], operands[0])
9264 || rtx_equal_p (operands[2], operands[1]))
9265 && ! FP_REG_P (operands[0])
9266 && ! FP_REG_P (operands[1])"
9270 [(set (match_operand:DI 0 "register_operand" "=r")
9271 (match_operand:DI 1 "register_operand" "r"))
9273 (compare:CCX (match_operand:DI 2 "register_operand" "r")
9276 && (rtx_equal_p (operands[2], operands[0])
9277 || rtx_equal_p (operands[2], operands[1]))
9278 && ! FP_REG_P (operands[0])
9279 && ! FP_REG_P (operands[1])"
9282 ;; Return peepholes. First the "normal" ones.
9283 ;; These are necessary to catch insns ending up in the epilogue delay list.
9285 (define_insn "*return_qi"
9286 [(set (match_operand:QI 0 "restore_operand" "")
9287 (match_operand:QI 1 "arith_operand" "rI"))
9292 if (! TARGET_ARCH64 && current_function_returns_struct)
9293 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9294 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9295 || IN_OR_GLOBAL_P (operands[1])))
9296 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9298 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9300 [(set_attr "type" "multi")])
9302 (define_insn "*return_hi"
9303 [(set (match_operand:HI 0 "restore_operand" "")
9304 (match_operand:HI 1 "arith_operand" "rI"))
9309 if (! TARGET_ARCH64 && current_function_returns_struct)
9310 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9311 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9312 || IN_OR_GLOBAL_P (operands[1])))
9313 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9315 return \"ret\;restore %%g0, %1, %Y0\";
9317 [(set_attr "type" "multi")])
9319 (define_insn "*return_si"
9320 [(set (match_operand:SI 0 "restore_operand" "")
9321 (match_operand:SI 1 "arith_operand" "rI"))
9326 if (! TARGET_ARCH64 && current_function_returns_struct)
9327 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9328 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9329 || IN_OR_GLOBAL_P (operands[1])))
9330 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9332 return \"ret\;restore %%g0, %1, %Y0\";
9334 [(set_attr "type" "multi")])
9336 ;; The following pattern is only generated by delayed-branch scheduling,
9337 ;; when the insn winds up in the epilogue. This can happen not only when
9338 ;; ! TARGET_FPU because we move complex types around by parts using
9340 (define_insn "*return_sf_no_fpu"
9341 [(set (match_operand:SF 0 "restore_operand" "=r")
9342 (match_operand:SF 1 "register_operand" "r"))
9347 if (! TARGET_ARCH64 && current_function_returns_struct)
9348 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9349 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9350 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9352 return \"ret\;restore %%g0, %1, %Y0\";
9354 [(set_attr "type" "multi")])
9356 (define_insn "*return_df_no_fpu"
9357 [(set (match_operand:DF 0 "restore_operand" "=r")
9358 (match_operand:DF 1 "register_operand" "r"))
9360 "! TARGET_EPILOGUE && TARGET_ARCH64"
9363 if (IN_OR_GLOBAL_P (operands[1]))
9364 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9366 return \"ret\;restore %%g0, %1, %Y0\";
9368 [(set_attr "type" "multi")])
9370 (define_insn "*return_addsi"
9371 [(set (match_operand:SI 0 "restore_operand" "")
9372 (plus:SI (match_operand:SI 1 "register_operand" "r")
9373 (match_operand:SI 2 "arith_operand" "rI")))
9378 if (! TARGET_ARCH64 && current_function_returns_struct)
9379 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9380 /* If operands are global or in registers, can use return */
9381 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9382 && (GET_CODE (operands[2]) == CONST_INT
9383 || IN_OR_GLOBAL_P (operands[2])))
9384 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9386 return \"ret\;restore %r1, %2, %Y0\";
9388 [(set_attr "type" "multi")])
9390 (define_insn "*return_losum_si"
9391 [(set (match_operand:SI 0 "restore_operand" "")
9392 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9393 (match_operand:SI 2 "immediate_operand" "in")))
9395 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9398 if (! TARGET_ARCH64 && current_function_returns_struct)
9399 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9400 /* If operands are global or in registers, can use return */
9401 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9402 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9404 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9406 [(set_attr "type" "multi")])
9408 (define_insn "*return_di"
9409 [(set (match_operand:DI 0 "restore_operand" "")
9410 (match_operand:DI 1 "arith_double_operand" "rHI"))
9412 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9413 "ret\;restore %%g0, %1, %Y0"
9414 [(set_attr "type" "multi")])
9416 (define_insn "*return_adddi"
9417 [(set (match_operand:DI 0 "restore_operand" "")
9418 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9419 (match_operand:DI 2 "arith_double_operand" "rHI")))
9421 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9422 "ret\;restore %r1, %2, %Y0"
9423 [(set_attr "type" "multi")])
9425 (define_insn "*return_losum_di"
9426 [(set (match_operand:DI 0 "restore_operand" "")
9427 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9428 (match_operand:DI 2 "immediate_operand" "in")))
9430 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9431 "ret\;restore %r1, %%lo(%a2), %Y0"
9432 [(set_attr "type" "multi")])
9434 ;; The following pattern is only generated by delayed-branch scheduling,
9435 ;; when the insn winds up in the epilogue.
9436 (define_insn "*return_sf"
9438 (match_operand:SF 0 "register_operand" "f"))
9441 "ret\;fmovs\\t%0, %%f0"
9442 [(set_attr "type" "multi")])
9444 ;; Now peepholes to do a call followed by a jump.
9447 [(parallel [(set (match_operand 0 "" "")
9448 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9449 (match_operand 2 "" "")))
9450 (clobber (reg:SI 15))])
9451 (set (pc) (label_ref (match_operand 3 "" "")))]
9452 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9453 && in_same_eh_region (insn, operands[3])
9454 && in_same_eh_region (insn, ins1)"
9455 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9458 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9459 (match_operand 1 "" ""))
9460 (clobber (reg:SI 15))])
9461 (set (pc) (label_ref (match_operand 2 "" "")))]
9462 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9463 && in_same_eh_region (insn, operands[2])
9464 && in_same_eh_region (insn, ins1)"
9465 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9468 [(parallel [(set (match_operand 0 "" "")
9469 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9470 (match_operand 2 "" "")))
9471 (clobber (reg:DI 15))])
9472 (set (pc) (label_ref (match_operand 3 "" "")))]
9474 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9475 && in_same_eh_region (insn, operands[3])
9476 && in_same_eh_region (insn, ins1)"
9477 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9480 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9481 (match_operand 1 "" ""))
9482 (clobber (reg:DI 15))])
9483 (set (pc) (label_ref (match_operand 2 "" "")))]
9485 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9486 && in_same_eh_region (insn, operands[2])
9487 && in_same_eh_region (insn, ins1)"
9488 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9490 (define_expand "prologue"
9492 "flag_pic && current_function_uses_pic_offset_table"
9495 load_pic_register ();
9499 ;; We need to reload %l7 for -mflat -fpic,
9500 ;; otherwise %l7 should be preserved simply
9501 ;; by loading the function's register window
9502 (define_expand "exception_receiver"
9504 "TARGET_FLAT && flag_pic"
9507 load_pic_register ();
9512 (define_expand "builtin_setjmp_receiver"
9513 [(label_ref (match_operand 0 "" ""))]
9514 "TARGET_FLAT && flag_pic"
9517 load_pic_register ();
9522 [(trap_if (const_int 1) (const_int 5))]
9525 [(set_attr "type" "misc")
9526 (set_attr "length" "1")])
9528 (define_expand "conditional_trap"
9529 [(trap_if (match_operator 0 "noov_compare_op"
9530 [(match_dup 2) (match_dup 3)])
9531 (match_operand:SI 1 "arith_operand" ""))]
9533 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9534 sparc_compare_op0, sparc_compare_op1);
9535 operands[3] = const0_rtx;")
9538 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9539 (match_operand:SI 1 "arith_operand" "rM"))]
9542 [(set_attr "type" "misc")
9543 (set_attr "length" "1")])
9546 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9547 (match_operand:SI 1 "arith_operand" "rM"))]
9550 [(set_attr "type" "misc")
9551 (set_attr "length" "1")])