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 = adjust_address (operands[1], SImode, 0);
2961 rtx word1 = adjust_address (operands[1], SImode, 4);
2962 rtx high_part = gen_highpart (SImode, operands[0]);
2963 rtx low_part = gen_lowpart (SImode, operands[0]);
2965 if (reg_overlap_mentioned_p (high_part, word1))
2967 emit_insn (gen_movsi (low_part, word1));
2968 emit_insn (gen_movsi (high_part, word0));
2972 emit_insn (gen_movsi (high_part, word0));
2973 emit_insn (gen_movsi (low_part, word1));
2979 [(set (match_operand:DI 0 "memory_operand" "")
2980 (match_operand:DI 1 "register_operand" ""))]
2983 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2984 [(clobber (const_int 0))]
2987 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2988 gen_highpart (SImode, operands[1])));
2989 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2990 gen_lowpart (SImode, operands[1])));
2995 ;; Floating point move insns
2997 (define_insn "*movsf_insn_novis"
2998 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2999 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
3000 "(TARGET_FPU && ! TARGET_VIS)
3001 && (register_operand (operands[0], SFmode)
3002 || register_operand (operands[1], SFmode)
3003 || fp_zero_operand (operands[1], SFmode))"
3006 if (GET_CODE (operands[1]) == CONST_DOUBLE
3007 && (which_alternative == 2
3008 || which_alternative == 3
3009 || which_alternative == 4))
3014 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3015 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3016 operands[1] = GEN_INT (i);
3019 switch (which_alternative)
3022 return \"fmovs\\t%1, %0\";
3024 return \"clr\\t%0\";
3026 return \"sethi\\t%%hi(%a1), %0\";
3028 return \"mov\\t%1, %0\";
3033 return \"ld\\t%1, %0\";
3036 return \"st\\t%r1, %0\";
3041 [(set_attr "type" "fpmove,move,move,move,*,load,fpload,fpstore,store")
3042 (set_attr "length" "1")])
3044 (define_insn "*movsf_insn_vis"
3045 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
3046 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
3047 "(TARGET_FPU && TARGET_VIS)
3048 && (register_operand (operands[0], SFmode)
3049 || register_operand (operands[1], SFmode)
3050 || fp_zero_operand (operands[1], SFmode))"
3053 if (GET_CODE (operands[1]) == CONST_DOUBLE
3054 && (which_alternative == 3
3055 || which_alternative == 4
3056 || which_alternative == 5))
3061 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3062 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3063 operands[1] = GEN_INT (i);
3066 switch (which_alternative)
3069 return \"fmovs\\t%1, %0\";
3071 return \"fzeros\\t%0\";
3073 return \"clr\\t%0\";
3075 return \"sethi\\t%%hi(%a1), %0\";
3077 return \"mov\\t%1, %0\";
3082 return \"ld\\t%1, %0\";
3085 return \"st\\t%r1, %0\";
3090 [(set_attr "type" "fpmove,fpmove,move,move,move,*,load,fpload,fpstore,store")
3091 (set_attr "length" "1")])
3093 ;; Exactly the same as above, except that all `f' cases are deleted.
3094 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3097 (define_insn "*movsf_no_f_insn"
3098 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
3099 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
3101 && (register_operand (operands[0], SFmode)
3102 || register_operand (operands[1], SFmode)
3103 || fp_zero_operand (operands[1], SFmode))"
3106 if (GET_CODE (operands[1]) == CONST_DOUBLE
3107 && (which_alternative == 1
3108 || which_alternative == 2
3109 || which_alternative == 3))
3114 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3115 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3116 operands[1] = GEN_INT (i);
3119 switch (which_alternative)
3122 return \"clr\\t%0\";
3124 return \"sethi\\t%%hi(%a1), %0\";
3126 return \"mov\\t%1, %0\";
3130 return \"ld\\t%1, %0\";
3132 return \"st\\t%r1, %0\";
3137 [(set_attr "type" "move,move,move,*,load,store")
3138 (set_attr "length" "1")])
3140 (define_insn "*movsf_lo_sum"
3141 [(set (match_operand:SF 0 "register_operand" "=r")
3142 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3143 (match_operand:SF 2 "const_double_operand" "S")))]
3144 "fp_high_losum_p (operands[2])"
3150 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3151 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3152 operands[2] = GEN_INT (i);
3153 return \"or\\t%1, %%lo(%a2), %0\";
3155 [(set_attr "type" "ialu")
3156 (set_attr "length" "1")])
3158 (define_insn "*movsf_high"
3159 [(set (match_operand:SF 0 "register_operand" "=r")
3160 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3161 "fp_high_losum_p (operands[1])"
3167 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3168 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3169 operands[1] = GEN_INT (i);
3170 return \"sethi\\t%%hi(%1), %0\";
3172 [(set_attr "type" "move")
3173 (set_attr "length" "1")])
3176 [(set (match_operand:SF 0 "register_operand" "")
3177 (match_operand:SF 1 "const_double_operand" ""))]
3178 "fp_high_losum_p (operands[1])
3179 && (GET_CODE (operands[0]) == REG
3180 && REGNO (operands[0]) < 32)"
3181 [(set (match_dup 0) (high:SF (match_dup 1)))
3182 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3184 (define_expand "movsf"
3185 [(set (match_operand:SF 0 "general_operand" "")
3186 (match_operand:SF 1 "general_operand" ""))]
3190 /* Force SFmode constants into memory. */
3191 if (GET_CODE (operands[0]) == REG
3192 && CONSTANT_P (operands[1]))
3194 /* emit_group_store will send such bogosity to us when it is
3195 not storing directly into memory. So fix this up to avoid
3196 crashes in output_constant_pool. */
3197 if (operands [1] == const0_rtx)
3198 operands[1] = CONST0_RTX (SFmode);
3200 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3203 /* We are able to build any SF constant in integer registers
3204 with at most 2 instructions. */
3205 if (REGNO (operands[0]) < 32)
3208 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3212 /* Handle sets of MEM first. */
3213 if (GET_CODE (operands[0]) == MEM)
3215 if (register_operand (operands[1], SFmode)
3216 || fp_zero_operand (operands[1], SFmode))
3219 if (! reload_in_progress)
3221 operands[0] = validize_mem (operands[0]);
3222 operands[1] = force_reg (SFmode, operands[1]);
3226 /* Fixup PIC cases. */
3229 if (CONSTANT_P (operands[1])
3230 && pic_address_needs_scratch (operands[1]))
3231 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3233 if (symbolic_operand (operands[1], SFmode))
3235 operands[1] = legitimize_pic_address (operands[1],
3237 (reload_in_progress ?
3247 (define_expand "movdf"
3248 [(set (match_operand:DF 0 "general_operand" "")
3249 (match_operand:DF 1 "general_operand" ""))]
3253 /* Force DFmode constants into memory. */
3254 if (GET_CODE (operands[0]) == REG
3255 && CONSTANT_P (operands[1]))
3257 /* emit_group_store will send such bogosity to us when it is
3258 not storing directly into memory. So fix this up to avoid
3259 crashes in output_constant_pool. */
3260 if (operands [1] == const0_rtx)
3261 operands[1] = CONST0_RTX (DFmode);
3263 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3264 && fp_zero_operand (operands[1], DFmode))
3267 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3271 /* Handle MEM cases first. */
3272 if (GET_CODE (operands[0]) == MEM)
3274 if (register_operand (operands[1], DFmode)
3275 || fp_zero_operand (operands[1], DFmode))
3278 if (! reload_in_progress)
3280 operands[0] = validize_mem (operands[0]);
3281 operands[1] = force_reg (DFmode, operands[1]);
3285 /* Fixup PIC cases. */
3288 if (CONSTANT_P (operands[1])
3289 && pic_address_needs_scratch (operands[1]))
3290 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3292 if (symbolic_operand (operands[1], DFmode))
3294 operands[1] = legitimize_pic_address (operands[1],
3296 (reload_in_progress ?
3306 ;; Be careful, fmovd does not exist when !v9.
3307 (define_insn "*movdf_insn_sp32"
3308 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3309 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3312 && (register_operand (operands[0], DFmode)
3313 || register_operand (operands[1], DFmode)
3314 || fp_zero_operand (operands[1], DFmode))"
3326 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3327 (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
3329 (define_insn "*movdf_no_e_insn_sp32"
3330 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3331 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3335 && (register_operand (operands[0], DFmode)
3336 || register_operand (operands[1], DFmode)
3337 || fp_zero_operand (operands[1], DFmode))"
3344 [(set_attr "type" "load,store,*,*,*")
3345 (set_attr "length" "1,1,2,2,2")])
3347 (define_insn "*movdf_no_e_insn_v9_sp32"
3348 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3349 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3353 && (register_operand (operands[0], DFmode)
3354 || register_operand (operands[1], DFmode)
3355 || fp_zero_operand (operands[1], DFmode))"
3362 [(set_attr "type" "load,store,store,*,*")
3363 (set_attr "length" "1,1,1,2,2")])
3365 ;; We have available v9 double floats but not 64-bit
3366 ;; integer registers and no VIS.
3367 (define_insn "*movdf_insn_v9only_novis"
3368 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3369 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3374 && (register_operand (operands[0], DFmode)
3375 || register_operand (operands[1], DFmode)
3376 || fp_zero_operand (operands[1], DFmode))"
3387 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3388 (set_attr "length" "1,1,1,1,1,1,2,2,2")])
3390 ;; We have available v9 double floats but not 64-bit
3391 ;; integer registers but we have VIS.
3392 (define_insn "*movdf_insn_v9only_vis"
3393 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3394 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3398 && (register_operand (operands[0], DFmode)
3399 || register_operand (operands[1], DFmode)
3400 || fp_zero_operand (operands[1], DFmode))"
3412 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3413 (set_attr "length" "1,1,1,1,1,1,1,2,2,2")])
3415 ;; We have available both v9 double floats and 64-bit
3416 ;; integer registers. No VIS though.
3417 (define_insn "*movdf_insn_sp64_novis"
3418 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3419 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3423 && (register_operand (operands[0], DFmode)
3424 || register_operand (operands[1], DFmode)
3425 || fp_zero_operand (operands[1], DFmode))"
3434 [(set_attr "type" "fpmove,load,store,move,load,store,*")
3435 (set_attr "length" "1,1,1,1,1,1,2")])
3437 ;; We have available both v9 double floats and 64-bit
3438 ;; integer registers. And we have VIS.
3439 (define_insn "*movdf_insn_sp64_vis"
3440 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3441 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3445 && (register_operand (operands[0], DFmode)
3446 || register_operand (operands[1], DFmode)
3447 || fp_zero_operand (operands[1], DFmode))"
3457 [(set_attr "type" "fpmove,fpmove,load,store,move,load,store,*")
3458 (set_attr "length" "1,1,1,1,1,1,1,2")])
3460 (define_insn "*movdf_no_e_insn_sp64"
3461 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3462 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3465 && (register_operand (operands[0], DFmode)
3466 || register_operand (operands[1], DFmode)
3467 || fp_zero_operand (operands[1], DFmode))"
3472 [(set_attr "type" "move,load,store")
3473 (set_attr "length" "1")])
3476 [(set (match_operand:DF 0 "register_operand" "")
3477 (match_operand:DF 1 "const_double_operand" ""))]
3479 && (GET_CODE (operands[0]) == REG
3480 && REGNO (operands[0]) < 32)
3481 && ! fp_zero_operand(operands[1], DFmode)
3482 && reload_completed"
3483 [(clobber (const_int 0))]
3489 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3490 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3491 if (GET_CODE (operands[0]) == SUBREG)
3492 operands[0] = alter_subreg (operands[0]);
3493 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3497 #if HOST_BITS_PER_WIDE_INT == 64
3500 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3501 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3502 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3504 emit_insn (gen_movdi (operands[0],
3505 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
3511 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3514 /* Slick... but this trick loses if this subreg constant part
3515 can be done in one insn. */
3517 && !(SPARC_SETHI_P (l[0])
3518 || SPARC_SIMM13_P (l[0])))
3520 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3521 gen_highpart (SImode, operands[0])));
3525 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3532 ;; Ok, now the splits to handle all the multi insn and
3533 ;; mis-aligned memory address cases.
3534 ;; In these splits please take note that we must be
3535 ;; careful when V9 but not ARCH64 because the integer
3536 ;; register DFmode cases must be handled.
3538 [(set (match_operand:DF 0 "register_operand" "")
3539 (match_operand:DF 1 "register_operand" ""))]
3542 && ((GET_CODE (operands[0]) == REG
3543 && REGNO (operands[0]) < 32)
3544 || (GET_CODE (operands[0]) == SUBREG
3545 && GET_CODE (SUBREG_REG (operands[0])) == REG
3546 && REGNO (SUBREG_REG (operands[0])) < 32))))
3547 && reload_completed"
3548 [(clobber (const_int 0))]
3551 rtx set_dest = operands[0];
3552 rtx set_src = operands[1];
3556 if (GET_CODE (set_dest) == SUBREG)
3557 set_dest = alter_subreg (set_dest);
3558 if (GET_CODE (set_src) == SUBREG)
3559 set_src = alter_subreg (set_src);
3561 dest1 = gen_highpart (SFmode, set_dest);
3562 dest2 = gen_lowpart (SFmode, set_dest);
3563 src1 = gen_highpart (SFmode, set_src);
3564 src2 = gen_lowpart (SFmode, set_src);
3566 /* Now emit using the real source and destination we found, swapping
3567 the order if we detect overlap. */
3568 if (reg_overlap_mentioned_p (dest1, src2))
3570 emit_insn (gen_movsf (dest2, src2));
3571 emit_insn (gen_movsf (dest1, src1));
3575 emit_insn (gen_movsf (dest1, src1));
3576 emit_insn (gen_movsf (dest2, src2));
3582 [(set (match_operand:DF 0 "register_operand" "")
3583 (match_operand:DF 1 "memory_operand" ""))]
3586 && (((REGNO (operands[0]) % 2) != 0)
3587 || ! mem_min_alignment (operands[1], 8))
3588 && offsettable_memref_p (operands[1])"
3589 [(clobber (const_int 0))]
3592 rtx word0 = adjust_address (operands[1], SFmode, 0);
3593 rtx word1 = adjust_address (operands[1], SFmode, 4);
3595 if (GET_CODE (operands[0]) == SUBREG)
3596 operands[0] = alter_subreg (operands[0]);
3598 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3600 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3602 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3607 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3609 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3616 [(set (match_operand:DF 0 "memory_operand" "")
3617 (match_operand:DF 1 "register_operand" ""))]
3620 && (((REGNO (operands[1]) % 2) != 0)
3621 || ! mem_min_alignment (operands[0], 8))
3622 && offsettable_memref_p (operands[0])"
3623 [(clobber (const_int 0))]
3626 rtx word0 = adjust_address (operands[0], SFmode, 0);
3627 rtx word1 = adjust_address (operands[0], SFmode, 4);
3629 if (GET_CODE (operands[1]) == SUBREG)
3630 operands[1] = alter_subreg (operands[1]);
3631 emit_insn (gen_movsf (word0,
3632 gen_highpart (SFmode, operands[1])));
3633 emit_insn (gen_movsf (word1,
3634 gen_lowpart (SFmode, operands[1])));
3639 [(set (match_operand:DF 0 "memory_operand" "")
3640 (match_operand:DF 1 "fp_zero_operand" ""))]
3644 && ! mem_min_alignment (operands[0], 8)))
3645 && offsettable_memref_p (operands[0])"
3646 [(clobber (const_int 0))]
3651 dest1 = adjust_address (operands[0], SFmode, 0);
3652 dest2 = adjust_address (operands[0], SFmode, 4);
3654 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3655 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3660 [(set (match_operand:DF 0 "register_operand" "")
3661 (match_operand:DF 1 "fp_zero_operand" ""))]
3664 && ((GET_CODE (operands[0]) == REG
3665 && REGNO (operands[0]) < 32)
3666 || (GET_CODE (operands[0]) == SUBREG
3667 && GET_CODE (SUBREG_REG (operands[0])) == REG
3668 && REGNO (SUBREG_REG (operands[0])) < 32))"
3669 [(clobber (const_int 0))]
3672 rtx set_dest = operands[0];
3675 if (GET_CODE (set_dest) == SUBREG)
3676 set_dest = alter_subreg (set_dest);
3677 dest1 = gen_highpart (SFmode, set_dest);
3678 dest2 = gen_lowpart (SFmode, set_dest);
3679 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3680 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3684 (define_expand "movtf"
3685 [(set (match_operand:TF 0 "general_operand" "")
3686 (match_operand:TF 1 "general_operand" ""))]
3690 /* Force TFmode constants into memory. */
3691 if (GET_CODE (operands[0]) == REG
3692 && CONSTANT_P (operands[1]))
3694 /* emit_group_store will send such bogosity to us when it is
3695 not storing directly into memory. So fix this up to avoid
3696 crashes in output_constant_pool. */
3697 if (operands [1] == const0_rtx)
3698 operands[1] = CONST0_RTX (TFmode);
3700 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3703 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3707 /* Handle MEM cases first, note that only v9 guarentees
3708 full 16-byte alignment for quads. */
3709 if (GET_CODE (operands[0]) == MEM)
3711 if (register_operand (operands[1], TFmode)
3712 || fp_zero_operand (operands[1], TFmode))
3715 if (! reload_in_progress)
3717 operands[0] = validize_mem (operands[0]);
3718 operands[1] = force_reg (TFmode, operands[1]);
3722 /* Fixup PIC cases. */
3725 if (CONSTANT_P (operands[1])
3726 && pic_address_needs_scratch (operands[1]))
3727 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3729 if (symbolic_operand (operands[1], TFmode))
3731 operands[1] = legitimize_pic_address (operands[1],
3733 (reload_in_progress ?
3743 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3744 ;; we must split them all. :-(
3745 (define_insn "*movtf_insn_sp32"
3746 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3747 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3751 && (register_operand (operands[0], TFmode)
3752 || register_operand (operands[1], TFmode)
3753 || fp_zero_operand (operands[1], TFmode))"
3755 [(set_attr "length" "4")])
3757 (define_insn "*movtf_insn_vis_sp32"
3758 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3759 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3763 && (register_operand (operands[0], TFmode)
3764 || register_operand (operands[1], TFmode)
3765 || fp_zero_operand (operands[1], TFmode))"
3767 [(set_attr "length" "4")])
3769 ;; Exactly the same as above, except that all `e' cases are deleted.
3770 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3773 (define_insn "*movtf_no_e_insn_sp32"
3774 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3775 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3778 && (register_operand (operands[0], TFmode)
3779 || register_operand (operands[1], TFmode)
3780 || fp_zero_operand (operands[1], TFmode))"
3782 [(set_attr "length" "4")])
3784 ;; Now handle the float reg cases directly when arch64,
3785 ;; hard_quad, and proper reg number alignment are all true.
3786 (define_insn "*movtf_insn_hq_sp64"
3787 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3788 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3793 && (register_operand (operands[0], TFmode)
3794 || register_operand (operands[1], TFmode)
3795 || fp_zero_operand (operands[1], TFmode))"
3802 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3803 (set_attr "length" "1,1,1,2,2")])
3805 (define_insn "*movtf_insn_hq_vis_sp64"
3806 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3807 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3812 && (register_operand (operands[0], TFmode)
3813 || register_operand (operands[1], TFmode)
3814 || fp_zero_operand (operands[1], TFmode))"
3822 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3823 (set_attr "length" "1,1,1,2,2,2")])
3825 ;; Now we allow the integer register cases even when
3826 ;; only arch64 is true.
3827 (define_insn "*movtf_insn_sp64"
3828 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3829 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3833 && ! TARGET_HARD_QUAD
3834 && (register_operand (operands[0], TFmode)
3835 || register_operand (operands[1], TFmode)
3836 || fp_zero_operand (operands[1], TFmode))"
3838 [(set_attr "length" "2")])
3840 (define_insn "*movtf_insn_vis_sp64"
3841 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3842 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3846 && ! TARGET_HARD_QUAD
3847 && (register_operand (operands[0], TFmode)
3848 || register_operand (operands[1], TFmode)
3849 || fp_zero_operand (operands[1], TFmode))"
3851 [(set_attr "length" "2")])
3853 (define_insn "*movtf_no_e_insn_sp64"
3854 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3855 (match_operand:TF 1 "input_operand" "orG,rG"))]
3858 && (register_operand (operands[0], TFmode)
3859 || register_operand (operands[1], TFmode)
3860 || fp_zero_operand (operands[1], TFmode))"
3862 [(set_attr "length" "2")])
3864 ;; Now all the splits to handle multi-insn TF mode moves.
3866 [(set (match_operand:TF 0 "register_operand" "")
3867 (match_operand:TF 1 "register_operand" ""))]
3871 && ! TARGET_HARD_QUAD))"
3872 [(clobber (const_int 0))]
3875 rtx set_dest = operands[0];
3876 rtx set_src = operands[1];
3880 if (GET_CODE (set_dest) == SUBREG)
3881 set_dest = alter_subreg (set_dest);
3882 if (GET_CODE (set_src) == SUBREG)
3883 set_src = alter_subreg (set_src);
3885 dest1 = gen_df_reg (set_dest, 0);
3886 dest2 = gen_df_reg (set_dest, 1);
3887 src1 = gen_df_reg (set_src, 0);
3888 src2 = gen_df_reg (set_src, 1);
3890 /* Now emit using the real source and destination we found, swapping
3891 the order if we detect overlap. */
3892 if (reg_overlap_mentioned_p (dest1, src2))
3894 emit_insn (gen_movdf (dest2, src2));
3895 emit_insn (gen_movdf (dest1, src1));
3899 emit_insn (gen_movdf (dest1, src1));
3900 emit_insn (gen_movdf (dest2, src2));
3906 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3907 (match_operand:TF 1 "fp_zero_operand" ""))]
3909 [(clobber (const_int 0))]
3912 rtx set_dest = operands[0];
3915 switch (GET_CODE (set_dest))
3918 set_dest = alter_subreg (set_dest);
3921 dest1 = gen_df_reg (set_dest, 0);
3922 dest2 = gen_df_reg (set_dest, 1);
3925 dest1 = adjust_address (set_dest, DFmode, 0);
3926 dest2 = adjust_address (set_dest, DFmode, 8);
3932 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3933 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3938 [(set (match_operand:TF 0 "register_operand" "")
3939 (match_operand:TF 1 "memory_operand" ""))]
3941 && offsettable_memref_p (operands[1]))"
3942 [(clobber (const_int 0))]
3945 rtx word0 = adjust_address (operands[1], DFmode, 0);
3946 rtx word1 = adjust_address (operands[1], DFmode, 8);
3947 rtx set_dest, dest1, dest2;
3949 set_dest = operands[0];
3950 if (GET_CODE (set_dest) == SUBREG)
3951 set_dest = alter_subreg (set_dest);
3953 dest1 = gen_df_reg (set_dest, 0);
3954 dest2 = gen_df_reg (set_dest, 1);
3956 /* Now output, ordering such that we don't clobber any registers
3957 mentioned in the address. */
3958 if (reg_overlap_mentioned_p (dest1, word1))
3961 emit_insn (gen_movdf (dest2, word1));
3962 emit_insn (gen_movdf (dest1, word0));
3966 emit_insn (gen_movdf (dest1, word0));
3967 emit_insn (gen_movdf (dest2, word1));
3973 [(set (match_operand:TF 0 "memory_operand" "")
3974 (match_operand:TF 1 "register_operand" ""))]
3976 && offsettable_memref_p (operands[0]))"
3977 [(clobber (const_int 0))]
3980 rtx set_src = operands[1];
3981 if (GET_CODE (set_src) == SUBREG)
3982 set_src = alter_subreg (set_src);
3984 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3985 gen_df_reg (set_src, 0)));
3986 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3987 gen_df_reg (set_src, 1)));
3991 ;; Sparc V9 conditional move instructions.
3993 ;; We can handle larger constants here for some flavors, but for now we keep
3994 ;; it simple and only allow those constants supported by all flavours.
3995 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3996 ;; 3 contains the constant if one is present, but we handle either for
3997 ;; generality (sparc.c puts a constant in operand 2).
3999 (define_expand "movqicc"
4000 [(set (match_operand:QI 0 "register_operand" "")
4001 (if_then_else:QI (match_operand 1 "comparison_operator" "")
4002 (match_operand:QI 2 "arith10_operand" "")
4003 (match_operand:QI 3 "arith10_operand" "")))]
4007 enum rtx_code code = GET_CODE (operands[1]);
4009 if (GET_MODE (sparc_compare_op0) == DImode
4013 if (sparc_compare_op1 == const0_rtx
4014 && GET_CODE (sparc_compare_op0) == REG
4015 && GET_MODE (sparc_compare_op0) == DImode
4016 && v9_regcmp_p (code))
4018 operands[1] = gen_rtx_fmt_ee (code, DImode,
4019 sparc_compare_op0, sparc_compare_op1);
4023 rtx cc_reg = gen_compare_reg (code,
4024 sparc_compare_op0, sparc_compare_op1);
4025 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4029 (define_expand "movhicc"
4030 [(set (match_operand:HI 0 "register_operand" "")
4031 (if_then_else:HI (match_operand 1 "comparison_operator" "")
4032 (match_operand:HI 2 "arith10_operand" "")
4033 (match_operand:HI 3 "arith10_operand" "")))]
4037 enum rtx_code code = GET_CODE (operands[1]);
4039 if (GET_MODE (sparc_compare_op0) == DImode
4043 if (sparc_compare_op1 == const0_rtx
4044 && GET_CODE (sparc_compare_op0) == REG
4045 && GET_MODE (sparc_compare_op0) == DImode
4046 && v9_regcmp_p (code))
4048 operands[1] = gen_rtx_fmt_ee (code, DImode,
4049 sparc_compare_op0, sparc_compare_op1);
4053 rtx cc_reg = gen_compare_reg (code,
4054 sparc_compare_op0, sparc_compare_op1);
4055 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4059 (define_expand "movsicc"
4060 [(set (match_operand:SI 0 "register_operand" "")
4061 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4062 (match_operand:SI 2 "arith10_operand" "")
4063 (match_operand:SI 3 "arith10_operand" "")))]
4067 enum rtx_code code = GET_CODE (operands[1]);
4068 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
4070 if (sparc_compare_op1 == const0_rtx
4071 && GET_CODE (sparc_compare_op0) == REG
4072 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
4074 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
4075 sparc_compare_op0, sparc_compare_op1);
4079 rtx cc_reg = gen_compare_reg (code,
4080 sparc_compare_op0, sparc_compare_op1);
4081 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4082 cc_reg, const0_rtx);
4086 (define_expand "movdicc"
4087 [(set (match_operand:DI 0 "register_operand" "")
4088 (if_then_else:DI (match_operand 1 "comparison_operator" "")
4089 (match_operand:DI 2 "arith10_double_operand" "")
4090 (match_operand:DI 3 "arith10_double_operand" "")))]
4094 enum rtx_code code = GET_CODE (operands[1]);
4096 if (sparc_compare_op1 == const0_rtx
4097 && GET_CODE (sparc_compare_op0) == REG
4098 && GET_MODE (sparc_compare_op0) == DImode
4099 && v9_regcmp_p (code))
4101 operands[1] = gen_rtx_fmt_ee (code, DImode,
4102 sparc_compare_op0, sparc_compare_op1);
4106 rtx cc_reg = gen_compare_reg (code,
4107 sparc_compare_op0, sparc_compare_op1);
4108 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4109 cc_reg, const0_rtx);
4113 (define_expand "movsfcc"
4114 [(set (match_operand:SF 0 "register_operand" "")
4115 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4116 (match_operand:SF 2 "register_operand" "")
4117 (match_operand:SF 3 "register_operand" "")))]
4118 "TARGET_V9 && TARGET_FPU"
4121 enum rtx_code code = GET_CODE (operands[1]);
4123 if (GET_MODE (sparc_compare_op0) == DImode
4127 if (sparc_compare_op1 == const0_rtx
4128 && GET_CODE (sparc_compare_op0) == REG
4129 && GET_MODE (sparc_compare_op0) == DImode
4130 && v9_regcmp_p (code))
4132 operands[1] = gen_rtx_fmt_ee (code, DImode,
4133 sparc_compare_op0, sparc_compare_op1);
4137 rtx cc_reg = gen_compare_reg (code,
4138 sparc_compare_op0, sparc_compare_op1);
4139 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4143 (define_expand "movdfcc"
4144 [(set (match_operand:DF 0 "register_operand" "")
4145 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4146 (match_operand:DF 2 "register_operand" "")
4147 (match_operand:DF 3 "register_operand" "")))]
4148 "TARGET_V9 && TARGET_FPU"
4151 enum rtx_code code = GET_CODE (operands[1]);
4153 if (GET_MODE (sparc_compare_op0) == DImode
4157 if (sparc_compare_op1 == const0_rtx
4158 && GET_CODE (sparc_compare_op0) == REG
4159 && GET_MODE (sparc_compare_op0) == DImode
4160 && v9_regcmp_p (code))
4162 operands[1] = gen_rtx_fmt_ee (code, DImode,
4163 sparc_compare_op0, sparc_compare_op1);
4167 rtx cc_reg = gen_compare_reg (code,
4168 sparc_compare_op0, sparc_compare_op1);
4169 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4173 (define_expand "movtfcc"
4174 [(set (match_operand:TF 0 "register_operand" "")
4175 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4176 (match_operand:TF 2 "register_operand" "")
4177 (match_operand:TF 3 "register_operand" "")))]
4178 "TARGET_V9 && TARGET_FPU"
4181 enum rtx_code code = GET_CODE (operands[1]);
4183 if (GET_MODE (sparc_compare_op0) == DImode
4187 if (sparc_compare_op1 == const0_rtx
4188 && GET_CODE (sparc_compare_op0) == REG
4189 && GET_MODE (sparc_compare_op0) == DImode
4190 && v9_regcmp_p (code))
4192 operands[1] = gen_rtx_fmt_ee (code, DImode,
4193 sparc_compare_op0, sparc_compare_op1);
4197 rtx cc_reg = gen_compare_reg (code,
4198 sparc_compare_op0, sparc_compare_op1);
4199 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4203 ;; Conditional move define_insns.
4205 (define_insn "*movqi_cc_sp64"
4206 [(set (match_operand:QI 0 "register_operand" "=r,r")
4207 (if_then_else:QI (match_operator 1 "comparison_operator"
4208 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4210 (match_operand:QI 3 "arith11_operand" "rL,0")
4211 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4214 mov%C1\\t%x2, %3, %0
4215 mov%c1\\t%x2, %4, %0"
4216 [(set_attr "type" "cmove")
4217 (set_attr "length" "1")])
4219 (define_insn "*movhi_cc_sp64"
4220 [(set (match_operand:HI 0 "register_operand" "=r,r")
4221 (if_then_else:HI (match_operator 1 "comparison_operator"
4222 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4224 (match_operand:HI 3 "arith11_operand" "rL,0")
4225 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4228 mov%C1\\t%x2, %3, %0
4229 mov%c1\\t%x2, %4, %0"
4230 [(set_attr "type" "cmove")
4231 (set_attr "length" "1")])
4233 (define_insn "*movsi_cc_sp64"
4234 [(set (match_operand:SI 0 "register_operand" "=r,r")
4235 (if_then_else:SI (match_operator 1 "comparison_operator"
4236 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4238 (match_operand:SI 3 "arith11_operand" "rL,0")
4239 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4242 mov%C1\\t%x2, %3, %0
4243 mov%c1\\t%x2, %4, %0"
4244 [(set_attr "type" "cmove")
4245 (set_attr "length" "1")])
4247 ;; ??? The constraints of operands 3,4 need work.
4248 (define_insn "*movdi_cc_sp64"
4249 [(set (match_operand:DI 0 "register_operand" "=r,r")
4250 (if_then_else:DI (match_operator 1 "comparison_operator"
4251 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4253 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4254 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4257 mov%C1\\t%x2, %3, %0
4258 mov%c1\\t%x2, %4, %0"
4259 [(set_attr "type" "cmove")
4260 (set_attr "length" "1")])
4262 (define_insn "*movdi_cc_sp64_trunc"
4263 [(set (match_operand:SI 0 "register_operand" "=r,r")
4264 (if_then_else:SI (match_operator 1 "comparison_operator"
4265 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4267 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4268 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4271 mov%C1\\t%x2, %3, %0
4272 mov%c1\\t%x2, %4, %0"
4273 [(set_attr "type" "cmove")
4274 (set_attr "length" "1")])
4276 (define_insn "*movsf_cc_sp64"
4277 [(set (match_operand:SF 0 "register_operand" "=f,f")
4278 (if_then_else:SF (match_operator 1 "comparison_operator"
4279 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4281 (match_operand:SF 3 "register_operand" "f,0")
4282 (match_operand:SF 4 "register_operand" "0,f")))]
4283 "TARGET_V9 && TARGET_FPU"
4285 fmovs%C1\\t%x2, %3, %0
4286 fmovs%c1\\t%x2, %4, %0"
4287 [(set_attr "type" "fpcmove")
4288 (set_attr "length" "1")])
4290 (define_insn "movdf_cc_sp64"
4291 [(set (match_operand:DF 0 "register_operand" "=e,e")
4292 (if_then_else:DF (match_operator 1 "comparison_operator"
4293 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4295 (match_operand:DF 3 "register_operand" "e,0")
4296 (match_operand:DF 4 "register_operand" "0,e")))]
4297 "TARGET_V9 && TARGET_FPU"
4299 fmovd%C1\\t%x2, %3, %0
4300 fmovd%c1\\t%x2, %4, %0"
4301 [(set_attr "type" "fpcmove")
4302 (set_attr "length" "1")])
4304 (define_insn "*movtf_cc_hq_sp64"
4305 [(set (match_operand:TF 0 "register_operand" "=e,e")
4306 (if_then_else:TF (match_operator 1 "comparison_operator"
4307 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4309 (match_operand:TF 3 "register_operand" "e,0")
4310 (match_operand:TF 4 "register_operand" "0,e")))]
4311 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4313 fmovq%C1\\t%x2, %3, %0
4314 fmovq%c1\\t%x2, %4, %0"
4315 [(set_attr "type" "fpcmove")
4316 (set_attr "length" "1")])
4318 (define_insn "*movtf_cc_sp64"
4319 [(set (match_operand:TF 0 "register_operand" "=e,e")
4320 (if_then_else:TF (match_operator 1 "comparison_operator"
4321 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4323 (match_operand:TF 3 "register_operand" "e,0")
4324 (match_operand:TF 4 "register_operand" "0,e")))]
4325 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4327 [(set_attr "type" "fpcmove")
4328 (set_attr "length" "2")])
4331 [(set (match_operand:TF 0 "register_operand" "=e,e")
4332 (if_then_else:TF (match_operator 1 "comparison_operator"
4333 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4335 (match_operand:TF 3 "register_operand" "e,0")
4336 (match_operand:TF 4 "register_operand" "0,e")))]
4337 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4338 [(clobber (const_int 0))]
4341 rtx set_dest = operands[0];
4342 rtx set_srca = operands[3];
4343 rtx set_srcb = operands[4];
4344 int third = rtx_equal_p (set_dest, set_srca);
4346 rtx srca1, srca2, srcb1, srcb2;
4348 if (GET_CODE (set_dest) == SUBREG)
4349 set_dest = alter_subreg (set_dest);
4350 if (GET_CODE (set_srca) == SUBREG)
4351 set_srca = alter_subreg (set_srca);
4352 if (GET_CODE (set_srcb) == SUBREG)
4353 set_srcb = alter_subreg (set_srcb);
4355 dest1 = gen_df_reg (set_dest, 0);
4356 dest2 = gen_df_reg (set_dest, 1);
4357 srca1 = gen_df_reg (set_srca, 0);
4358 srca2 = gen_df_reg (set_srca, 1);
4359 srcb1 = gen_df_reg (set_srcb, 0);
4360 srcb2 = gen_df_reg (set_srcb, 1);
4362 /* Now emit using the real source and destination we found, swapping
4363 the order if we detect overlap. */
4364 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4365 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4367 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4368 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4372 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4373 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4378 (define_insn "*movqi_cc_reg_sp64"
4379 [(set (match_operand:QI 0 "register_operand" "=r,r")
4380 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4381 [(match_operand:DI 2 "register_operand" "r,r")
4383 (match_operand:QI 3 "arith10_operand" "rM,0")
4384 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4387 movr%D1\\t%2, %r3, %0
4388 movr%d1\\t%2, %r4, %0"
4389 [(set_attr "type" "cmove")
4390 (set_attr "length" "1")])
4392 (define_insn "*movhi_cc_reg_sp64"
4393 [(set (match_operand:HI 0 "register_operand" "=r,r")
4394 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4395 [(match_operand:DI 2 "register_operand" "r,r")
4397 (match_operand:HI 3 "arith10_operand" "rM,0")
4398 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4401 movr%D1\\t%2, %r3, %0
4402 movr%d1\\t%2, %r4, %0"
4403 [(set_attr "type" "cmove")
4404 (set_attr "length" "1")])
4406 (define_insn "*movsi_cc_reg_sp64"
4407 [(set (match_operand:SI 0 "register_operand" "=r,r")
4408 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4409 [(match_operand:DI 2 "register_operand" "r,r")
4411 (match_operand:SI 3 "arith10_operand" "rM,0")
4412 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4415 movr%D1\\t%2, %r3, %0
4416 movr%d1\\t%2, %r4, %0"
4417 [(set_attr "type" "cmove")
4418 (set_attr "length" "1")])
4420 ;; ??? The constraints of operands 3,4 need work.
4421 (define_insn "*movdi_cc_reg_sp64"
4422 [(set (match_operand:DI 0 "register_operand" "=r,r")
4423 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4424 [(match_operand:DI 2 "register_operand" "r,r")
4426 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4427 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4430 movr%D1\\t%2, %r3, %0
4431 movr%d1\\t%2, %r4, %0"
4432 [(set_attr "type" "cmove")
4433 (set_attr "length" "1")])
4435 (define_insn "*movdi_cc_reg_sp64_trunc"
4436 [(set (match_operand:SI 0 "register_operand" "=r,r")
4437 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4438 [(match_operand:DI 2 "register_operand" "r,r")
4440 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4441 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4444 movr%D1\\t%2, %r3, %0
4445 movr%d1\\t%2, %r4, %0"
4446 [(set_attr "type" "cmove")
4447 (set_attr "length" "1")])
4449 (define_insn "*movsf_cc_reg_sp64"
4450 [(set (match_operand:SF 0 "register_operand" "=f,f")
4451 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4452 [(match_operand:DI 2 "register_operand" "r,r")
4454 (match_operand:SF 3 "register_operand" "f,0")
4455 (match_operand:SF 4 "register_operand" "0,f")))]
4456 "TARGET_ARCH64 && TARGET_FPU"
4458 fmovrs%D1\\t%2, %3, %0
4459 fmovrs%d1\\t%2, %4, %0"
4460 [(set_attr "type" "fpcmove")
4461 (set_attr "length" "1")])
4463 (define_insn "movdf_cc_reg_sp64"
4464 [(set (match_operand:DF 0 "register_operand" "=e,e")
4465 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4466 [(match_operand:DI 2 "register_operand" "r,r")
4468 (match_operand:DF 3 "register_operand" "e,0")
4469 (match_operand:DF 4 "register_operand" "0,e")))]
4470 "TARGET_ARCH64 && TARGET_FPU"
4472 fmovrd%D1\\t%2, %3, %0
4473 fmovrd%d1\\t%2, %4, %0"
4474 [(set_attr "type" "fpcmove")
4475 (set_attr "length" "1")])
4477 (define_insn "*movtf_cc_reg_hq_sp64"
4478 [(set (match_operand:TF 0 "register_operand" "=e,e")
4479 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4480 [(match_operand:DI 2 "register_operand" "r,r")
4482 (match_operand:TF 3 "register_operand" "e,0")
4483 (match_operand:TF 4 "register_operand" "0,e")))]
4484 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4486 fmovrq%D1\\t%2, %3, %0
4487 fmovrq%d1\\t%2, %4, %0"
4488 [(set_attr "type" "fpcmove")
4489 (set_attr "length" "1")])
4491 (define_insn "*movtf_cc_reg_sp64"
4492 [(set (match_operand:TF 0 "register_operand" "=e,e")
4493 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4494 [(match_operand:DI 2 "register_operand" "r,r")
4496 (match_operand:TF 3 "register_operand" "e,0")
4497 (match_operand:TF 4 "register_operand" "0,e")))]
4498 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4500 [(set_attr "type" "fpcmove")
4501 (set_attr "length" "2")])
4504 [(set (match_operand:TF 0 "register_operand" "=e,e")
4505 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4506 [(match_operand:DI 2 "register_operand" "r,r")
4508 (match_operand:TF 3 "register_operand" "e,0")
4509 (match_operand:TF 4 "register_operand" "0,e")))]
4510 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4511 [(clobber (const_int 0))]
4514 rtx set_dest = operands[0];
4515 rtx set_srca = operands[3];
4516 rtx set_srcb = operands[4];
4517 int third = rtx_equal_p (set_dest, set_srca);
4519 rtx srca1, srca2, srcb1, srcb2;
4521 if (GET_CODE (set_dest) == SUBREG)
4522 set_dest = alter_subreg (set_dest);
4523 if (GET_CODE (set_srca) == SUBREG)
4524 set_srca = alter_subreg (set_srca);
4525 if (GET_CODE (set_srcb) == SUBREG)
4526 set_srcb = alter_subreg (set_srcb);
4528 dest1 = gen_df_reg (set_dest, 0);
4529 dest2 = gen_df_reg (set_dest, 1);
4530 srca1 = gen_df_reg (set_srca, 0);
4531 srca2 = gen_df_reg (set_srca, 1);
4532 srcb1 = gen_df_reg (set_srcb, 0);
4533 srcb2 = gen_df_reg (set_srcb, 1);
4535 /* Now emit using the real source and destination we found, swapping
4536 the order if we detect overlap. */
4537 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4538 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4540 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4541 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4545 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4546 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4552 ;;- zero extension instructions
4554 ;; These patterns originally accepted general_operands, however, slightly
4555 ;; better code is generated by only accepting register_operands, and then
4556 ;; letting combine generate the ldu[hb] insns.
4558 (define_expand "zero_extendhisi2"
4559 [(set (match_operand:SI 0 "register_operand" "")
4560 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4564 rtx temp = gen_reg_rtx (SImode);
4565 rtx shift_16 = GEN_INT (16);
4566 int op1_subbyte = 0;
4568 if (GET_CODE (operand1) == SUBREG)
4570 op1_subbyte = SUBREG_BYTE (operand1);
4571 op1_subbyte /= GET_MODE_SIZE (SImode);
4572 op1_subbyte *= GET_MODE_SIZE (SImode);
4573 operand1 = XEXP (operand1, 0);
4576 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4578 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4582 (define_insn "*zero_extendhisi2_insn"
4583 [(set (match_operand:SI 0 "register_operand" "=r")
4584 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4587 [(set_attr "type" "load")
4588 (set_attr "length" "1")])
4590 (define_expand "zero_extendqihi2"
4591 [(set (match_operand:HI 0 "register_operand" "")
4592 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4596 (define_insn "*zero_extendqihi2_insn"
4597 [(set (match_operand:HI 0 "register_operand" "=r,r")
4598 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4599 "GET_CODE (operands[1]) != CONST_INT"
4603 [(set_attr "type" "unary,load")
4604 (set_attr "length" "1")])
4606 (define_expand "zero_extendqisi2"
4607 [(set (match_operand:SI 0 "register_operand" "")
4608 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4612 (define_insn "*zero_extendqisi2_insn"
4613 [(set (match_operand:SI 0 "register_operand" "=r,r")
4614 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4615 "GET_CODE (operands[1]) != CONST_INT"
4619 [(set_attr "type" "unary,load")
4620 (set_attr "length" "1")])
4622 (define_expand "zero_extendqidi2"
4623 [(set (match_operand:DI 0 "register_operand" "")
4624 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4628 (define_insn "*zero_extendqidi2_insn"
4629 [(set (match_operand:DI 0 "register_operand" "=r,r")
4630 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4631 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4635 [(set_attr "type" "unary,load")
4636 (set_attr "length" "1")])
4638 (define_expand "zero_extendhidi2"
4639 [(set (match_operand:DI 0 "register_operand" "")
4640 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4644 rtx temp = gen_reg_rtx (DImode);
4645 rtx shift_48 = GEN_INT (48);
4646 int op1_subbyte = 0;
4648 if (GET_CODE (operand1) == SUBREG)
4650 op1_subbyte = SUBREG_BYTE (operand1);
4651 op1_subbyte /= GET_MODE_SIZE (DImode);
4652 op1_subbyte *= GET_MODE_SIZE (DImode);
4653 operand1 = XEXP (operand1, 0);
4656 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4658 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4662 (define_insn "*zero_extendhidi2_insn"
4663 [(set (match_operand:DI 0 "register_operand" "=r")
4664 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4667 [(set_attr "type" "load")
4668 (set_attr "length" "1")])
4671 ;; ??? Write truncdisi pattern using sra?
4673 (define_expand "zero_extendsidi2"
4674 [(set (match_operand:DI 0 "register_operand" "")
4675 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4679 (define_insn "*zero_extendsidi2_insn_sp64"
4680 [(set (match_operand:DI 0 "register_operand" "=r,r")
4681 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4682 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4686 [(set_attr "type" "shift,load")
4687 (set_attr "length" "1")])
4689 (define_insn "*zero_extendsidi2_insn_sp32"
4690 [(set (match_operand:DI 0 "register_operand" "=r")
4691 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4694 [(set_attr "type" "unary")
4695 (set_attr "length" "2")])
4698 [(set (match_operand:DI 0 "register_operand" "")
4699 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4700 "! TARGET_ARCH64 && reload_completed"
4701 [(set (match_dup 2) (match_dup 3))
4702 (set (match_dup 4) (match_dup 5))]
4707 if (GET_CODE (operands[0]) == SUBREG)
4708 operands[0] = alter_subreg (operands[0]);
4710 dest1 = gen_highpart (SImode, operands[0]);
4711 dest2 = gen_lowpart (SImode, operands[0]);
4713 /* Swap the order in case of overlap. */
4714 if (REGNO (dest1) == REGNO (operands[1]))
4716 operands[2] = dest2;
4717 operands[3] = operands[1];
4718 operands[4] = dest1;
4719 operands[5] = const0_rtx;
4723 operands[2] = dest1;
4724 operands[3] = const0_rtx;
4725 operands[4] = dest2;
4726 operands[5] = operands[1];
4730 ;; Simplify comparisons of extended values.
4732 (define_insn "*cmp_zero_extendqisi2"
4734 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4737 "andcc\\t%0, 0xff, %%g0"
4738 [(set_attr "type" "compare")
4739 (set_attr "length" "1")])
4741 (define_insn "*cmp_zero_qi"
4743 (compare:CC (match_operand:QI 0 "register_operand" "r")
4746 "andcc\\t%0, 0xff, %%g0"
4747 [(set_attr "type" "compare")
4748 (set_attr "length" "1")])
4750 (define_insn "*cmp_zero_extendqisi2_set"
4752 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4754 (set (match_operand:SI 0 "register_operand" "=r")
4755 (zero_extend:SI (match_dup 1)))]
4757 "andcc\\t%1, 0xff, %0"
4758 [(set_attr "type" "compare")
4759 (set_attr "length" "1")])
4761 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4763 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4766 (set (match_operand:SI 0 "register_operand" "=r")
4767 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4769 "andcc\\t%1, 0xff, %0"
4770 [(set_attr "type" "compare")
4771 (set_attr "length" "1")])
4773 (define_insn "*cmp_zero_extendqidi2"
4775 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4778 "andcc\\t%0, 0xff, %%g0"
4779 [(set_attr "type" "compare")
4780 (set_attr "length" "1")])
4782 (define_insn "*cmp_zero_qi_sp64"
4784 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4787 "andcc\\t%0, 0xff, %%g0"
4788 [(set_attr "type" "compare")
4789 (set_attr "length" "1")])
4791 (define_insn "*cmp_zero_extendqidi2_set"
4793 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4795 (set (match_operand:DI 0 "register_operand" "=r")
4796 (zero_extend:DI (match_dup 1)))]
4798 "andcc\\t%1, 0xff, %0"
4799 [(set_attr "type" "compare")
4800 (set_attr "length" "1")])
4802 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4804 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4807 (set (match_operand:DI 0 "register_operand" "=r")
4808 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4810 "andcc\\t%1, 0xff, %0"
4811 [(set_attr "type" "compare")
4812 (set_attr "length" "1")])
4814 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4816 (define_insn "*cmp_siqi_trunc"
4818 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4821 "andcc\\t%0, 0xff, %%g0"
4822 [(set_attr "type" "compare")
4823 (set_attr "length" "1")])
4825 (define_insn "*cmp_siqi_trunc_set"
4827 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4829 (set (match_operand:QI 0 "register_operand" "=r")
4830 (subreg:QI (match_dup 1) 3))]
4832 "andcc\\t%1, 0xff, %0"
4833 [(set_attr "type" "compare")
4834 (set_attr "length" "1")])
4836 (define_insn "*cmp_diqi_trunc"
4838 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4841 "andcc\\t%0, 0xff, %%g0"
4842 [(set_attr "type" "compare")
4843 (set_attr "length" "1")])
4845 (define_insn "*cmp_diqi_trunc_set"
4847 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4849 (set (match_operand:QI 0 "register_operand" "=r")
4850 (subreg:QI (match_dup 1) 7))]
4852 "andcc\\t%1, 0xff, %0"
4853 [(set_attr "type" "compare")
4854 (set_attr "length" "1")])
4856 ;;- sign extension instructions
4858 ;; These patterns originally accepted general_operands, however, slightly
4859 ;; better code is generated by only accepting register_operands, and then
4860 ;; letting combine generate the lds[hb] insns.
4862 (define_expand "extendhisi2"
4863 [(set (match_operand:SI 0 "register_operand" "")
4864 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4868 rtx temp = gen_reg_rtx (SImode);
4869 rtx shift_16 = GEN_INT (16);
4870 int op1_subbyte = 0;
4872 if (GET_CODE (operand1) == SUBREG)
4874 op1_subbyte = SUBREG_BYTE (operand1);
4875 op1_subbyte /= GET_MODE_SIZE (SImode);
4876 op1_subbyte *= GET_MODE_SIZE (SImode);
4877 operand1 = XEXP (operand1, 0);
4880 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4882 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4886 (define_insn "*sign_extendhisi2_insn"
4887 [(set (match_operand:SI 0 "register_operand" "=r")
4888 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4891 [(set_attr "type" "sload")
4892 (set_attr "length" "1")])
4894 (define_expand "extendqihi2"
4895 [(set (match_operand:HI 0 "register_operand" "")
4896 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4900 rtx temp = gen_reg_rtx (SImode);
4901 rtx shift_24 = GEN_INT (24);
4902 int op1_subbyte = 0;
4903 int op0_subbyte = 0;
4905 if (GET_CODE (operand1) == SUBREG)
4907 op1_subbyte = SUBREG_BYTE (operand1);
4908 op1_subbyte /= GET_MODE_SIZE (SImode);
4909 op1_subbyte *= GET_MODE_SIZE (SImode);
4910 operand1 = XEXP (operand1, 0);
4912 if (GET_CODE (operand0) == SUBREG)
4914 op0_subbyte = SUBREG_BYTE (operand0);
4915 op0_subbyte /= GET_MODE_SIZE (SImode);
4916 op0_subbyte *= GET_MODE_SIZE (SImode);
4917 operand0 = XEXP (operand0, 0);
4919 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4921 if (GET_MODE (operand0) != SImode)
4922 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4923 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4927 (define_insn "*sign_extendqihi2_insn"
4928 [(set (match_operand:HI 0 "register_operand" "=r")
4929 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4932 [(set_attr "type" "sload")
4933 (set_attr "length" "1")])
4935 (define_expand "extendqisi2"
4936 [(set (match_operand:SI 0 "register_operand" "")
4937 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4941 rtx temp = gen_reg_rtx (SImode);
4942 rtx shift_24 = GEN_INT (24);
4943 int op1_subbyte = 0;
4945 if (GET_CODE (operand1) == SUBREG)
4947 op1_subbyte = SUBREG_BYTE (operand1);
4948 op1_subbyte /= GET_MODE_SIZE (SImode);
4949 op1_subbyte *= GET_MODE_SIZE (SImode);
4950 operand1 = XEXP (operand1, 0);
4953 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4955 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4959 (define_insn "*sign_extendqisi2_insn"
4960 [(set (match_operand:SI 0 "register_operand" "=r")
4961 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4964 [(set_attr "type" "sload")
4965 (set_attr "length" "1")])
4967 (define_expand "extendqidi2"
4968 [(set (match_operand:DI 0 "register_operand" "")
4969 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4973 rtx temp = gen_reg_rtx (DImode);
4974 rtx shift_56 = GEN_INT (56);
4975 int op1_subbyte = 0;
4977 if (GET_CODE (operand1) == SUBREG)
4979 op1_subbyte = SUBREG_BYTE (operand1);
4980 op1_subbyte /= GET_MODE_SIZE (DImode);
4981 op1_subbyte *= GET_MODE_SIZE (DImode);
4982 operand1 = XEXP (operand1, 0);
4985 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4987 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4991 (define_insn "*sign_extendqidi2_insn"
4992 [(set (match_operand:DI 0 "register_operand" "=r")
4993 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4996 [(set_attr "type" "sload")
4997 (set_attr "length" "1")])
4999 (define_expand "extendhidi2"
5000 [(set (match_operand:DI 0 "register_operand" "")
5001 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
5005 rtx temp = gen_reg_rtx (DImode);
5006 rtx shift_48 = GEN_INT (48);
5007 int op1_subbyte = 0;
5009 if (GET_CODE (operand1) == SUBREG)
5011 op1_subbyte = SUBREG_BYTE (operand1);
5012 op1_subbyte /= GET_MODE_SIZE (DImode);
5013 op1_subbyte *= GET_MODE_SIZE (DImode);
5014 operand1 = XEXP (operand1, 0);
5017 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
5019 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
5023 (define_insn "*sign_extendhidi2_insn"
5024 [(set (match_operand:DI 0 "register_operand" "=r")
5025 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
5028 [(set_attr "type" "sload")
5029 (set_attr "length" "1")])
5031 (define_expand "extendsidi2"
5032 [(set (match_operand:DI 0 "register_operand" "")
5033 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
5037 (define_insn "*sign_extendsidi2_insn"
5038 [(set (match_operand:DI 0 "register_operand" "=r,r")
5039 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
5044 [(set_attr "type" "shift,sload")
5045 (set_attr "length" "1")])
5047 ;; Special pattern for optimizing bit-field compares. This is needed
5048 ;; because combine uses this as a canonical form.
5050 (define_insn "*cmp_zero_extract"
5053 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
5054 (match_operand:SI 1 "small_int_or_double" "n")
5055 (match_operand:SI 2 "small_int_or_double" "n"))
5057 "(GET_CODE (operands[2]) == CONST_INT
5058 && INTVAL (operands[2]) > 19)
5059 || (GET_CODE (operands[2]) == CONST_DOUBLE
5060 && CONST_DOUBLE_LOW (operands[2]) > 19)"
5063 int len = (GET_CODE (operands[1]) == CONST_INT
5064 ? INTVAL (operands[1])
5065 : CONST_DOUBLE_LOW (operands[1]));
5067 (GET_CODE (operands[2]) == CONST_INT
5068 ? INTVAL (operands[2])
5069 : CONST_DOUBLE_LOW (operands[2])) - len;
5070 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
5072 operands[1] = GEN_INT (mask);
5073 return \"andcc\\t%0, %1, %%g0\";
5075 [(set_attr "type" "compare")
5076 (set_attr "length" "1")])
5078 (define_insn "*cmp_zero_extract_sp64"
5081 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
5082 (match_operand:SI 1 "small_int_or_double" "n")
5083 (match_operand:SI 2 "small_int_or_double" "n"))
5086 && ((GET_CODE (operands[2]) == CONST_INT
5087 && INTVAL (operands[2]) > 51)
5088 || (GET_CODE (operands[2]) == CONST_DOUBLE
5089 && CONST_DOUBLE_LOW (operands[2]) > 51))"
5092 int len = (GET_CODE (operands[1]) == CONST_INT
5093 ? INTVAL (operands[1])
5094 : CONST_DOUBLE_LOW (operands[1]));
5096 (GET_CODE (operands[2]) == CONST_INT
5097 ? INTVAL (operands[2])
5098 : CONST_DOUBLE_LOW (operands[2])) - len;
5099 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
5101 operands[1] = GEN_INT (mask);
5102 return \"andcc\\t%0, %1, %%g0\";
5104 [(set_attr "type" "compare")
5105 (set_attr "length" "1")])
5107 ;; Conversions between float, double and long double.
5109 (define_insn "extendsfdf2"
5110 [(set (match_operand:DF 0 "register_operand" "=e")
5112 (match_operand:SF 1 "register_operand" "f")))]
5115 [(set_attr "type" "fp")
5116 (set_attr "length" "1")])
5118 (define_expand "extendsftf2"
5119 [(set (match_operand:TF 0 "register_operand" "=e")
5121 (match_operand:SF 1 "register_operand" "f")))]
5122 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5125 if (! TARGET_HARD_QUAD)
5129 if (GET_CODE (operands[0]) != MEM)
5130 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5132 slot0 = operands[0];
5134 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
5136 XEXP (slot0, 0), Pmode,
5137 operands[1], SFmode);
5139 if (GET_CODE (operands[0]) != MEM)
5140 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5145 (define_insn "*extendsftf2_hq"
5146 [(set (match_operand:TF 0 "register_operand" "=e")
5148 (match_operand:SF 1 "register_operand" "f")))]
5149 "TARGET_FPU && TARGET_HARD_QUAD"
5151 [(set_attr "type" "fp")
5152 (set_attr "length" "1")])
5154 (define_expand "extenddftf2"
5155 [(set (match_operand:TF 0 "register_operand" "=e")
5157 (match_operand:DF 1 "register_operand" "e")))]
5158 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5161 if (! TARGET_HARD_QUAD)
5165 if (GET_CODE (operands[0]) != MEM)
5166 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5168 slot0 = operands[0];
5170 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5172 XEXP (slot0, 0), Pmode,
5173 operands[1], DFmode);
5175 if (GET_CODE (operands[0]) != MEM)
5176 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5181 (define_insn "*extenddftf2_hq"
5182 [(set (match_operand:TF 0 "register_operand" "=e")
5184 (match_operand:DF 1 "register_operand" "e")))]
5185 "TARGET_FPU && TARGET_HARD_QUAD"
5187 [(set_attr "type" "fp")
5188 (set_attr "length" "1")])
5190 (define_insn "truncdfsf2"
5191 [(set (match_operand:SF 0 "register_operand" "=f")
5193 (match_operand:DF 1 "register_operand" "e")))]
5196 [(set_attr "type" "fp")
5197 (set_attr "length" "1")])
5199 (define_expand "trunctfsf2"
5200 [(set (match_operand:SF 0 "register_operand" "=f")
5202 (match_operand:TF 1 "register_operand" "e")))]
5203 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5206 if (! TARGET_HARD_QUAD)
5210 if (GET_CODE (operands[1]) != MEM)
5212 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5213 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5216 slot0 = operands[1];
5218 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5219 operands[0], 0, SFmode, 1,
5220 XEXP (slot0, 0), Pmode);
5225 (define_insn "*trunctfsf2_hq"
5226 [(set (match_operand:SF 0 "register_operand" "=f")
5228 (match_operand:TF 1 "register_operand" "e")))]
5229 "TARGET_FPU && TARGET_HARD_QUAD"
5231 [(set_attr "type" "fp")
5232 (set_attr "length" "1")])
5234 (define_expand "trunctfdf2"
5235 [(set (match_operand:DF 0 "register_operand" "=f")
5237 (match_operand:TF 1 "register_operand" "e")))]
5238 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5241 if (! TARGET_HARD_QUAD)
5245 if (GET_CODE (operands[1]) != MEM)
5247 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5248 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5251 slot0 = operands[1];
5253 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5254 operands[0], 0, DFmode, 1,
5255 XEXP (slot0, 0), Pmode);
5260 (define_insn "*trunctfdf2_hq"
5261 [(set (match_operand:DF 0 "register_operand" "=e")
5263 (match_operand:TF 1 "register_operand" "e")))]
5264 "TARGET_FPU && TARGET_HARD_QUAD"
5266 [(set_attr "type" "fp")
5267 (set_attr "length" "1")])
5269 ;; Conversion between fixed point and floating point.
5271 (define_insn "floatsisf2"
5272 [(set (match_operand:SF 0 "register_operand" "=f")
5273 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5276 [(set_attr "type" "fp")
5277 (set_attr "length" "1")])
5279 (define_insn "floatsidf2"
5280 [(set (match_operand:DF 0 "register_operand" "=e")
5281 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5284 [(set_attr "type" "fp")
5285 (set_attr "length" "1")])
5287 (define_expand "floatsitf2"
5288 [(set (match_operand:TF 0 "register_operand" "=e")
5289 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5290 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5293 if (! TARGET_HARD_QUAD)
5297 if (GET_CODE (operands[1]) != MEM)
5298 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5300 slot0 = operands[1];
5302 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5304 XEXP (slot0, 0), Pmode,
5305 operands[1], SImode);
5307 if (GET_CODE (operands[0]) != MEM)
5308 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5313 (define_insn "*floatsitf2_hq"
5314 [(set (match_operand:TF 0 "register_operand" "=e")
5315 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5316 "TARGET_FPU && TARGET_HARD_QUAD"
5318 [(set_attr "type" "fp")
5319 (set_attr "length" "1")])
5321 (define_expand "floatunssitf2"
5322 [(set (match_operand:TF 0 "register_operand" "=e")
5323 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5324 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5329 if (GET_CODE (operands[1]) != MEM)
5330 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5332 slot0 = operands[1];
5334 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5336 XEXP (slot0, 0), Pmode,
5337 operands[1], SImode);
5339 if (GET_CODE (operands[0]) != MEM)
5340 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5344 ;; Now the same for 64 bit sources.
5346 (define_insn "floatdisf2"
5347 [(set (match_operand:SF 0 "register_operand" "=f")
5348 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5349 "TARGET_V9 && TARGET_FPU"
5351 [(set_attr "type" "fp")
5352 (set_attr "length" "1")])
5354 (define_insn "floatdidf2"
5355 [(set (match_operand:DF 0 "register_operand" "=e")
5356 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5357 "TARGET_V9 && TARGET_FPU"
5359 [(set_attr "type" "fp")
5360 (set_attr "length" "1")])
5362 (define_expand "floatditf2"
5363 [(set (match_operand:TF 0 "register_operand" "=e")
5364 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5365 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5368 if (! TARGET_HARD_QUAD)
5372 if (GET_CODE (operands[1]) != MEM)
5373 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5375 slot0 = operands[1];
5377 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5379 XEXP (slot0, 0), Pmode,
5380 operands[1], DImode);
5382 if (GET_CODE (operands[0]) != MEM)
5383 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5388 (define_insn "*floatditf2_hq"
5389 [(set (match_operand:TF 0 "register_operand" "=e")
5390 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5391 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5393 [(set_attr "type" "fp")
5394 (set_attr "length" "1")])
5396 (define_expand "floatunsditf2"
5397 [(set (match_operand:TF 0 "register_operand" "=e")
5398 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5399 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5404 if (GET_CODE (operands[1]) != MEM)
5405 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5407 slot0 = operands[1];
5409 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5411 XEXP (slot0, 0), Pmode,
5412 operands[1], DImode);
5414 if (GET_CODE (operands[0]) != MEM)
5415 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5419 ;; Convert a float to an actual integer.
5420 ;; Truncation is performed as part of the conversion.
5422 (define_insn "fix_truncsfsi2"
5423 [(set (match_operand:SI 0 "register_operand" "=f")
5424 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5427 [(set_attr "type" "fp")
5428 (set_attr "length" "1")])
5430 (define_insn "fix_truncdfsi2"
5431 [(set (match_operand:SI 0 "register_operand" "=f")
5432 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5435 [(set_attr "type" "fp")
5436 (set_attr "length" "1")])
5438 (define_expand "fix_trunctfsi2"
5439 [(set (match_operand:SI 0 "register_operand" "=f")
5440 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5441 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5444 if (! TARGET_HARD_QUAD)
5448 if (GET_CODE (operands[1]) != MEM)
5450 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5451 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5454 slot0 = operands[1];
5456 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5457 operands[0], 0, SImode, 1,
5458 XEXP (slot0, 0), Pmode);
5463 (define_insn "*fix_trunctfsi2_hq"
5464 [(set (match_operand:SI 0 "register_operand" "=f")
5465 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5466 "TARGET_FPU && TARGET_HARD_QUAD"
5468 [(set_attr "type" "fp")
5469 (set_attr "length" "1")])
5471 (define_expand "fixuns_trunctfsi2"
5472 [(set (match_operand:SI 0 "register_operand" "=f")
5473 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5474 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5479 if (GET_CODE (operands[1]) != MEM)
5481 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5482 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5485 slot0 = operands[1];
5487 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5488 operands[0], 0, SImode, 1,
5489 XEXP (slot0, 0), Pmode);
5493 ;; Now the same, for V9 targets
5495 (define_insn "fix_truncsfdi2"
5496 [(set (match_operand:DI 0 "register_operand" "=e")
5497 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5498 "TARGET_V9 && TARGET_FPU"
5500 [(set_attr "type" "fp")
5501 (set_attr "length" "1")])
5503 (define_insn "fix_truncdfdi2"
5504 [(set (match_operand:DI 0 "register_operand" "=e")
5505 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5506 "TARGET_V9 && TARGET_FPU"
5508 [(set_attr "type" "fp")
5509 (set_attr "length" "1")])
5511 (define_expand "fix_trunctfdi2"
5512 [(set (match_operand:DI 0 "register_operand" "=e")
5513 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5514 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5517 if (! TARGET_HARD_QUAD)
5521 if (GET_CODE (operands[1]) != MEM)
5523 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5524 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5527 slot0 = operands[1];
5529 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5530 operands[0], 0, DImode, 1,
5531 XEXP (slot0, 0), Pmode);
5536 (define_insn "*fix_trunctfdi2_hq"
5537 [(set (match_operand:DI 0 "register_operand" "=e")
5538 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5539 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5541 [(set_attr "type" "fp")
5542 (set_attr "length" "1")])
5544 (define_expand "fixuns_trunctfdi2"
5545 [(set (match_operand:DI 0 "register_operand" "=f")
5546 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5547 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5552 if (GET_CODE (operands[1]) != MEM)
5554 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5555 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5558 slot0 = operands[1];
5560 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5561 operands[0], 0, DImode, 1,
5562 XEXP (slot0, 0), Pmode);
5567 ;;- arithmetic instructions
5569 (define_expand "adddi3"
5570 [(set (match_operand:DI 0 "register_operand" "=r")
5571 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5572 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5578 if (! TARGET_ARCH64)
5580 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5581 gen_rtx_SET (VOIDmode, operands[0],
5582 gen_rtx_PLUS (DImode, operands[1],
5584 gen_rtx_CLOBBER (VOIDmode,
5585 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5588 if (arith_double_4096_operand(operands[2], DImode))
5590 switch (GET_CODE (operands[1]))
5592 case CONST_INT: i = INTVAL (operands[1]); break;
5593 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5595 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5596 gen_rtx_MINUS (DImode, operands[1],
5600 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5605 (define_insn "adddi3_insn_sp32"
5606 [(set (match_operand:DI 0 "register_operand" "=r")
5607 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5608 (match_operand:DI 2 "arith_double_operand" "rHI")))
5609 (clobber (reg:CC 100))]
5612 [(set_attr "length" "2")])
5615 [(set (match_operand:DI 0 "register_operand" "=r")
5616 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5617 (match_operand:DI 2 "arith_double_operand" "rHI")))
5618 (clobber (reg:CC 100))]
5619 "! TARGET_ARCH64 && reload_completed"
5620 [(parallel [(set (reg:CC_NOOV 100)
5621 (compare:CC_NOOV (plus:SI (match_dup 4)
5625 (plus:SI (match_dup 4) (match_dup 5)))])
5627 (plus:SI (plus:SI (match_dup 7)
5629 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5632 operands[3] = gen_lowpart (SImode, operands[0]);
5633 operands[4] = gen_lowpart (SImode, operands[1]);
5634 operands[5] = gen_lowpart (SImode, operands[2]);
5635 operands[6] = gen_highpart (SImode, operands[0]);
5636 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5637 #if HOST_BITS_PER_WIDE_INT == 32
5638 if (GET_CODE (operands[2]) == CONST_INT)
5640 if (INTVAL (operands[2]) < 0)
5641 operands[8] = constm1_rtx;
5643 operands[8] = const0_rtx;
5647 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5651 [(set (match_operand:DI 0 "register_operand" "=r")
5652 (minus:DI (match_operand:DI 1 "arith_double_operand" "r")
5653 (match_operand:DI 2 "arith_double_operand" "rHI")))
5654 (clobber (reg:CC 100))]
5655 "! TARGET_ARCH64 && reload_completed"
5656 [(parallel [(set (reg:CC_NOOV 100)
5657 (compare:CC_NOOV (minus:SI (match_dup 4)
5661 (minus:SI (match_dup 4) (match_dup 5)))])
5663 (minus:SI (minus:SI (match_dup 7)
5665 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5668 operands[3] = gen_lowpart (SImode, operands[0]);
5669 operands[4] = gen_lowpart (SImode, operands[1]);
5670 operands[5] = gen_lowpart (SImode, operands[2]);
5671 operands[6] = gen_highpart (SImode, operands[0]);
5672 operands[7] = gen_highpart (SImode, operands[1]);
5673 #if HOST_BITS_PER_WIDE_INT == 32
5674 if (GET_CODE (operands[2]) == CONST_INT)
5676 if (INTVAL (operands[2]) < 0)
5677 operands[8] = constm1_rtx;
5679 operands[8] = const0_rtx;
5683 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5686 ;; LTU here means "carry set"
5688 [(set (match_operand:SI 0 "register_operand" "=r")
5689 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5690 (match_operand:SI 2 "arith_operand" "rI"))
5691 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5694 [(set_attr "type" "unary")
5695 (set_attr "length" "1")])
5697 (define_insn "*addx_extend_sp32"
5698 [(set (match_operand:DI 0 "register_operand" "=r")
5699 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5700 (match_operand:SI 2 "arith_operand" "rI"))
5701 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5704 [(set_attr "type" "unary")
5705 (set_attr "length" "2")])
5708 [(set (match_operand:DI 0 "register_operand" "")
5709 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5710 (match_operand:SI 2 "arith_operand" ""))
5711 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5712 "! TARGET_ARCH64 && reload_completed"
5713 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5714 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5715 (set (match_dup 4) (const_int 0))]
5716 "operands[3] = gen_lowpart (SImode, operands[0]);
5717 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5719 (define_insn "*addx_extend_sp64"
5720 [(set (match_operand:DI 0 "register_operand" "=r")
5721 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5722 (match_operand:SI 2 "arith_operand" "rI"))
5723 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5725 "addx\\t%r1, %2, %0"
5726 [(set_attr "type" "misc")
5727 (set_attr "length" "1")])
5730 [(set (match_operand:SI 0 "register_operand" "=r")
5731 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5732 (match_operand:SI 2 "arith_operand" "rI"))
5733 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5735 "subx\\t%r1, %2, %0"
5736 [(set_attr "type" "misc")
5737 (set_attr "length" "1")])
5739 (define_insn "*subx_extend_sp64"
5740 [(set (match_operand:DI 0 "register_operand" "=r")
5741 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5742 (match_operand:SI 2 "arith_operand" "rI"))
5743 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5745 "subx\\t%r1, %2, %0"
5746 [(set_attr "type" "misc")
5747 (set_attr "length" "1")])
5749 (define_insn "*subx_extend"
5750 [(set (match_operand:DI 0 "register_operand" "=r")
5751 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5752 (match_operand:SI 2 "arith_operand" "rI"))
5753 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5756 [(set_attr "type" "unary")
5757 (set_attr "length" "2")])
5760 [(set (match_operand:DI 0 "register_operand" "=r")
5761 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5762 (match_operand:SI 2 "arith_operand" "rI"))
5763 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5764 "! TARGET_ARCH64 && reload_completed"
5765 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5766 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5767 (set (match_dup 4) (const_int 0))]
5768 "operands[3] = gen_lowpart (SImode, operands[0]);
5769 operands[4] = gen_highpart (SImode, operands[0]);")
5772 [(set (match_operand:DI 0 "register_operand" "=r")
5773 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5774 (match_operand:DI 2 "register_operand" "r")))
5775 (clobber (reg:CC 100))]
5778 [(set_attr "type" "multi")
5779 (set_attr "length" "2")])
5782 [(set (match_operand:DI 0 "register_operand" "")
5783 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5784 (match_operand:DI 2 "register_operand" "")))
5785 (clobber (reg:CC 100))]
5786 "! TARGET_ARCH64 && reload_completed"
5787 [(parallel [(set (reg:CC_NOOV 100)
5788 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5790 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5792 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5793 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5794 "operands[3] = gen_lowpart (SImode, operands[2]);
5795 operands[4] = gen_highpart (SImode, operands[2]);
5796 operands[5] = gen_lowpart (SImode, operands[0]);
5797 operands[6] = gen_highpart (SImode, operands[0]);")
5799 (define_insn "*adddi3_sp64"
5800 [(set (match_operand:DI 0 "register_operand" "=r")
5801 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5802 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5805 [(set_attr "type" "binary")
5806 (set_attr "length" "1")])
5808 (define_expand "addsi3"
5809 [(set (match_operand:SI 0 "register_operand" "=r,d")
5810 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5811 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5815 if (arith_4096_operand(operands[2], SImode))
5817 if (GET_CODE (operands[1]) == CONST_INT)
5818 emit_insn (gen_movsi (operands[0],
5819 GEN_INT (INTVAL (operands[1]) + 4096)));
5821 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5822 gen_rtx_MINUS (SImode, operands[1],
5828 (define_insn "*addsi3"
5829 [(set (match_operand:SI 0 "register_operand" "=r,d")
5830 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5831 (match_operand:SI 2 "arith_operand" "rI,d")))]
5835 fpadd32s\\t%1, %2, %0"
5836 [(set_attr "type" "ialu,fp")
5837 (set_attr "length" "1")])
5839 (define_insn "*cmp_cc_plus"
5840 [(set (reg:CC_NOOV 100)
5841 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5842 (match_operand:SI 1 "arith_operand" "rI"))
5845 "addcc\\t%0, %1, %%g0"
5846 [(set_attr "type" "compare")
5847 (set_attr "length" "1")])
5849 (define_insn "*cmp_ccx_plus"
5850 [(set (reg:CCX_NOOV 100)
5851 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5852 (match_operand:DI 1 "arith_double_operand" "rHI"))
5855 "addcc\\t%0, %1, %%g0"
5856 [(set_attr "type" "compare")
5857 (set_attr "length" "1")])
5859 (define_insn "*cmp_cc_plus_set"
5860 [(set (reg:CC_NOOV 100)
5861 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5862 (match_operand:SI 2 "arith_operand" "rI"))
5864 (set (match_operand:SI 0 "register_operand" "=r")
5865 (plus:SI (match_dup 1) (match_dup 2)))]
5867 "addcc\\t%1, %2, %0"
5868 [(set_attr "type" "compare")
5869 (set_attr "length" "1")])
5871 (define_insn "*cmp_ccx_plus_set"
5872 [(set (reg:CCX_NOOV 100)
5873 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5874 (match_operand:DI 2 "arith_double_operand" "rHI"))
5876 (set (match_operand:DI 0 "register_operand" "=r")
5877 (plus:DI (match_dup 1) (match_dup 2)))]
5879 "addcc\\t%1, %2, %0"
5880 [(set_attr "type" "compare")
5881 (set_attr "length" "1")])
5883 (define_expand "subdi3"
5884 [(set (match_operand:DI 0 "register_operand" "=r")
5885 (minus:DI (match_operand:DI 1 "register_operand" "r")
5886 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5890 if (! TARGET_ARCH64)
5892 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5893 gen_rtx_SET (VOIDmode, operands[0],
5894 gen_rtx_MINUS (DImode, operands[1],
5896 gen_rtx_CLOBBER (VOIDmode,
5897 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5900 if (arith_double_4096_operand(operands[2], DImode))
5902 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5903 gen_rtx_PLUS (DImode, operands[1],
5909 (define_insn "*subdi3_sp32"
5910 [(set (match_operand:DI 0 "register_operand" "=r")
5911 (minus:DI (match_operand:DI 1 "register_operand" "r")
5912 (match_operand:DI 2 "arith_double_operand" "rHI")))
5913 (clobber (reg:CC 100))]
5916 [(set_attr "length" "2")])
5919 [(set (match_operand:DI 0 "register_operand" "")
5920 (minus:DI (match_operand:DI 1 "register_operand" "")
5921 (match_operand:DI 2 "arith_double_operand" "")))
5922 (clobber (reg:CC 100))]
5925 && (GET_CODE (operands[2]) == CONST_INT
5926 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5927 [(clobber (const_int 0))]
5932 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5933 lowp = gen_lowpart (SImode, operands[2]);
5934 if ((lowp == const0_rtx)
5935 && (operands[0] == operands[1]))
5937 emit_insn (gen_rtx_SET (VOIDmode,
5938 gen_highpart (SImode, operands[0]),
5939 gen_rtx_MINUS (SImode,
5940 gen_highpart_mode (SImode, DImode,
5946 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5947 gen_lowpart (SImode, operands[1]),
5949 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5950 gen_highpart_mode (SImode, DImode, operands[1]),
5957 [(set (match_operand:DI 0 "register_operand" "")
5958 (minus:DI (match_operand:DI 1 "register_operand" "")
5959 (match_operand:DI 2 "register_operand" "")))
5960 (clobber (reg:CC 100))]
5962 && reload_completed"
5963 [(clobber (const_int 0))]
5966 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5967 gen_lowpart (SImode, operands[1]),
5968 gen_lowpart (SImode, operands[2])));
5969 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5970 gen_highpart (SImode, operands[1]),
5971 gen_highpart (SImode, operands[2])));
5976 [(set (match_operand:DI 0 "register_operand" "=r")
5977 (minus:DI (match_operand:DI 1 "register_operand" "r")
5978 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5979 (clobber (reg:CC 100))]
5982 [(set_attr "type" "multi")
5983 (set_attr "length" "2")])
5986 [(set (match_operand:DI 0 "register_operand" "")
5987 (minus:DI (match_operand:DI 1 "register_operand" "")
5988 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5989 (clobber (reg:CC 100))]
5990 "! TARGET_ARCH64 && reload_completed"
5991 [(parallel [(set (reg:CC_NOOV 100)
5992 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5994 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5996 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5997 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5998 "operands[3] = gen_lowpart (SImode, operands[1]);
5999 operands[4] = gen_highpart (SImode, operands[1]);
6000 operands[5] = gen_lowpart (SImode, operands[0]);
6001 operands[6] = gen_highpart (SImode, operands[0]);")
6003 (define_insn "*subdi3_sp64"
6004 [(set (match_operand:DI 0 "register_operand" "=r")
6005 (minus:DI (match_operand:DI 1 "register_operand" "r")
6006 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6009 [(set_attr "type" "binary")
6010 (set_attr "length" "1")])
6012 (define_expand "subsi3"
6013 [(set (match_operand:SI 0 "register_operand" "=r,d")
6014 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
6015 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
6019 if (arith_4096_operand(operands[2], SImode))
6021 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
6022 gen_rtx_PLUS (SImode, operands[1],
6028 (define_insn "*subsi3"
6029 [(set (match_operand:SI 0 "register_operand" "=r,d")
6030 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
6031 (match_operand:SI 2 "arith_operand" "rI,d")))]
6035 fpsub32s\\t%1, %2, %0"
6036 [(set_attr "type" "ialu,fp")
6037 (set_attr "length" "1")])
6039 (define_insn "*cmp_minus_cc"
6040 [(set (reg:CC_NOOV 100)
6041 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
6042 (match_operand:SI 1 "arith_operand" "rI"))
6045 "subcc\\t%r0, %1, %%g0"
6046 [(set_attr "type" "compare")
6047 (set_attr "length" "1")])
6049 (define_insn "*cmp_minus_ccx"
6050 [(set (reg:CCX_NOOV 100)
6051 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
6052 (match_operand:DI 1 "arith_double_operand" "rHI"))
6055 "subcc\\t%0, %1, %%g0"
6056 [(set_attr "type" "compare")
6057 (set_attr "length" "1")])
6059 (define_insn "cmp_minus_cc_set"
6060 [(set (reg:CC_NOOV 100)
6061 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
6062 (match_operand:SI 2 "arith_operand" "rI"))
6064 (set (match_operand:SI 0 "register_operand" "=r")
6065 (minus:SI (match_dup 1) (match_dup 2)))]
6067 "subcc\\t%r1, %2, %0"
6068 [(set_attr "type" "compare")
6069 (set_attr "length" "1")])
6071 (define_insn "*cmp_minus_ccx_set"
6072 [(set (reg:CCX_NOOV 100)
6073 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
6074 (match_operand:DI 2 "arith_double_operand" "rHI"))
6076 (set (match_operand:DI 0 "register_operand" "=r")
6077 (minus:DI (match_dup 1) (match_dup 2)))]
6079 "subcc\\t%1, %2, %0"
6080 [(set_attr "type" "compare")
6081 (set_attr "length" "1")])
6083 ;; Integer Multiply/Divide.
6085 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
6086 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
6088 (define_insn "mulsi3"
6089 [(set (match_operand:SI 0 "register_operand" "=r")
6090 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6091 (match_operand:SI 2 "arith_operand" "rI")))]
6094 [(set_attr "type" "imul")
6095 (set_attr "length" "1")])
6097 (define_expand "muldi3"
6098 [(set (match_operand:DI 0 "register_operand" "=r")
6099 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6100 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6101 "TARGET_ARCH64 || TARGET_V8PLUS"
6106 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
6111 (define_insn "*muldi3_sp64"
6112 [(set (match_operand:DI 0 "register_operand" "=r")
6113 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6114 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6117 [(set_attr "type" "imul")
6118 (set_attr "length" "1")])
6120 ;; V8plus wide multiply.
6122 (define_insn "muldi3_v8plus"
6123 [(set (match_operand:DI 0 "register_operand" "=r,h")
6124 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
6125 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
6126 (clobber (match_scratch:SI 3 "=&h,X"))
6127 (clobber (match_scratch:SI 4 "=&h,X"))]
6131 if (sparc_check_64 (operands[1], insn) <= 0)
6132 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
6133 if (which_alternative == 1)
6134 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
6135 if (GET_CODE (operands[2]) == CONST_INT)
6137 if (which_alternative == 1)
6138 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
6140 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\";
6142 if (sparc_check_64 (operands[2], insn) <= 0)
6143 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6144 if (which_alternative == 1)
6145 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\";
6147 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\";
6149 [(set_attr "length" "9,8")])
6151 (define_insn "*cmp_mul_set"
6153 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6154 (match_operand:SI 2 "arith_operand" "rI"))
6156 (set (match_operand:SI 0 "register_operand" "=r")
6157 (mult:SI (match_dup 1) (match_dup 2)))]
6158 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6159 "smulcc\\t%1, %2, %0"
6160 [(set_attr "type" "imul")
6161 (set_attr "length" "1")])
6163 (define_expand "mulsidi3"
6164 [(set (match_operand:DI 0 "register_operand" "")
6165 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6166 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6170 if (CONSTANT_P (operands[2]))
6173 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6176 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6182 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6187 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6188 ;; registers can hold 64 bit values in the V8plus environment.
6190 (define_insn "mulsidi3_v8plus"
6191 [(set (match_operand:DI 0 "register_operand" "=h,r")
6192 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6193 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6194 (clobber (match_scratch:SI 3 "=X,&h"))]
6197 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6198 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6199 [(set_attr "length" "2,3")])
6202 (define_insn "const_mulsidi3_v8plus"
6203 [(set (match_operand:DI 0 "register_operand" "=h,r")
6204 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6205 (match_operand:SI 2 "small_int" "I,I")))
6206 (clobber (match_scratch:SI 3 "=X,&h"))]
6209 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6210 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6211 [(set_attr "length" "2,3")])
6214 (define_insn "*mulsidi3_sp32"
6215 [(set (match_operand:DI 0 "register_operand" "=r")
6216 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6217 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6221 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6223 [(set (attr "length")
6224 (if_then_else (eq_attr "isa" "sparclet")
6225 (const_int 1) (const_int 2)))])
6227 (define_insn "*mulsidi3_sp64"
6228 [(set (match_operand:DI 0 "register_operand" "=r")
6229 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6230 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6231 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6233 [(set_attr "length" "1")])
6235 ;; Extra pattern, because sign_extend of a constant isn't valid.
6238 (define_insn "const_mulsidi3_sp32"
6239 [(set (match_operand:DI 0 "register_operand" "=r")
6240 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6241 (match_operand:SI 2 "small_int" "I")))]
6245 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6247 [(set (attr "length")
6248 (if_then_else (eq_attr "isa" "sparclet")
6249 (const_int 1) (const_int 2)))])
6251 (define_insn "const_mulsidi3_sp64"
6252 [(set (match_operand:DI 0 "register_operand" "=r")
6253 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6254 (match_operand:SI 2 "small_int" "I")))]
6255 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6257 [(set_attr "length" "1")])
6259 (define_expand "smulsi3_highpart"
6260 [(set (match_operand:SI 0 "register_operand" "")
6262 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6263 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6265 "TARGET_HARD_MUL && TARGET_ARCH32"
6268 if (CONSTANT_P (operands[2]))
6272 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6278 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6283 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6284 operands[2], GEN_INT (32)));
6290 (define_insn "smulsi3_highpart_v8plus"
6291 [(set (match_operand:SI 0 "register_operand" "=h,r")
6293 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6294 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6295 (match_operand:SI 3 "const_int_operand" "i,i"))))
6296 (clobber (match_scratch:SI 4 "=X,&h"))]
6299 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6300 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6301 [(set_attr "length" "2")])
6303 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6306 [(set (match_operand:SI 0 "register_operand" "=h,r")
6309 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6310 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6311 (match_operand:SI 3 "const_int_operand" "i,i"))
6313 (clobber (match_scratch:SI 4 "=X,&h"))]
6316 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6317 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6318 [(set_attr "length" "2")])
6321 (define_insn "const_smulsi3_highpart_v8plus"
6322 [(set (match_operand:SI 0 "register_operand" "=h,r")
6324 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6325 (match_operand 2 "small_int" "i,i"))
6326 (match_operand:SI 3 "const_int_operand" "i,i"))))
6327 (clobber (match_scratch:SI 4 "=X,&h"))]
6330 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6331 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6332 [(set_attr "length" "2")])
6335 (define_insn "*smulsi3_highpart_sp32"
6336 [(set (match_operand:SI 0 "register_operand" "=r")
6338 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6339 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6342 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6343 [(set_attr "length" "2")])
6346 (define_insn "const_smulsi3_highpart"
6347 [(set (match_operand:SI 0 "register_operand" "=r")
6349 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6350 (match_operand:SI 2 "register_operand" "r"))
6353 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6354 [(set_attr "length" "2")])
6356 (define_expand "umulsidi3"
6357 [(set (match_operand:DI 0 "register_operand" "")
6358 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6359 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6363 if (CONSTANT_P (operands[2]))
6366 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6369 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6375 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6381 (define_insn "umulsidi3_v8plus"
6382 [(set (match_operand:DI 0 "register_operand" "=h,r")
6383 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6384 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6385 (clobber (match_scratch:SI 3 "=X,&h"))]
6388 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6389 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6390 [(set_attr "length" "2,3")])
6393 (define_insn "*umulsidi3_sp32"
6394 [(set (match_operand:DI 0 "register_operand" "=r")
6395 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6396 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6400 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6402 [(set (attr "length")
6403 (if_then_else (eq_attr "isa" "sparclet")
6404 (const_int 1) (const_int 2)))])
6406 (define_insn "*umulsidi3_sp64"
6407 [(set (match_operand:DI 0 "register_operand" "=r")
6408 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6409 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6410 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6412 [(set_attr "length" "1")])
6414 ;; Extra pattern, because sign_extend of a constant isn't valid.
6417 (define_insn "const_umulsidi3_sp32"
6418 [(set (match_operand:DI 0 "register_operand" "=r")
6419 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6420 (match_operand:SI 2 "uns_small_int" "")))]
6424 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6426 [(set (attr "length")
6427 (if_then_else (eq_attr "isa" "sparclet")
6428 (const_int 1) (const_int 2)))])
6430 (define_insn "const_umulsidi3_sp64"
6431 [(set (match_operand:DI 0 "register_operand" "=r")
6432 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6433 (match_operand:SI 2 "uns_small_int" "")))]
6434 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6436 [(set_attr "length" "1")])
6439 (define_insn "const_umulsidi3_v8plus"
6440 [(set (match_operand:DI 0 "register_operand" "=h,r")
6441 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6442 (match_operand:SI 2 "uns_small_int" "")))
6443 (clobber (match_scratch:SI 3 "=X,h"))]
6446 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6447 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6448 [(set_attr "length" "2,3")])
6450 (define_expand "umulsi3_highpart"
6451 [(set (match_operand:SI 0 "register_operand" "")
6453 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6454 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6456 "TARGET_HARD_MUL && TARGET_ARCH32"
6459 if (CONSTANT_P (operands[2]))
6463 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6469 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6474 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6475 operands[2], GEN_INT (32)));
6481 (define_insn "umulsi3_highpart_v8plus"
6482 [(set (match_operand:SI 0 "register_operand" "=h,r")
6484 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6485 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6486 (match_operand:SI 3 "const_int_operand" "i,i"))))
6487 (clobber (match_scratch:SI 4 "=X,h"))]
6490 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6491 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6492 [(set_attr "length" "2")])
6495 (define_insn "const_umulsi3_highpart_v8plus"
6496 [(set (match_operand:SI 0 "register_operand" "=h,r")
6498 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6499 (match_operand:SI 2 "uns_small_int" ""))
6500 (match_operand:SI 3 "const_int_operand" "i,i"))))
6501 (clobber (match_scratch:SI 4 "=X,h"))]
6504 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6505 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6506 [(set_attr "length" "2")])
6509 (define_insn "*umulsi3_highpart_sp32"
6510 [(set (match_operand:SI 0 "register_operand" "=r")
6512 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6513 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6516 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6517 [(set_attr "length" "2")])
6520 (define_insn "const_umulsi3_highpart"
6521 [(set (match_operand:SI 0 "register_operand" "=r")
6523 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6524 (match_operand:SI 2 "uns_small_int" ""))
6527 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6528 [(set_attr "length" "2")])
6530 ;; The v8 architecture specifies that there must be 3 instructions between
6531 ;; a y register write and a use of it for correct results.
6533 (define_expand "divsi3"
6534 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6535 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6536 (match_operand:SI 2 "input_operand" "rI,m")))
6537 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6538 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6543 operands[3] = gen_reg_rtx(SImode);
6544 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6545 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6551 (define_insn "divsi3_sp32"
6552 [(set (match_operand:SI 0 "register_operand" "=r,r")
6553 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6554 (match_operand:SI 2 "input_operand" "rI,m")))
6555 (clobber (match_scratch:SI 3 "=&r,&r"))]
6556 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6560 if (which_alternative == 0)
6562 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6564 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6567 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6569 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\";
6571 [(set (attr "length")
6572 (if_then_else (eq_attr "isa" "v9")
6573 (const_int 4) (const_int 7)))])
6575 (define_insn "divsi3_sp64"
6576 [(set (match_operand:SI 0 "register_operand" "=r")
6577 (div:SI (match_operand:SI 1 "register_operand" "r")
6578 (match_operand:SI 2 "input_operand" "rI")))
6579 (use (match_operand:SI 3 "register_operand" "r"))]
6580 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6581 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6582 [(set_attr "length" "2")])
6584 (define_insn "divdi3"
6585 [(set (match_operand:DI 0 "register_operand" "=r")
6586 (div:DI (match_operand:DI 1 "register_operand" "r")
6587 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6589 "sdivx\\t%1, %2, %0")
6591 (define_insn "*cmp_sdiv_cc_set"
6593 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6594 (match_operand:SI 2 "arith_operand" "rI"))
6596 (set (match_operand:SI 0 "register_operand" "=r")
6597 (div:SI (match_dup 1) (match_dup 2)))
6598 (clobber (match_scratch:SI 3 "=&r"))]
6599 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6603 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6605 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6607 [(set (attr "length")
6608 (if_then_else (eq_attr "isa" "v9")
6609 (const_int 3) (const_int 6)))])
6612 (define_expand "udivsi3"
6613 [(set (match_operand:SI 0 "register_operand" "")
6614 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6615 (match_operand:SI 2 "input_operand" "")))]
6616 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6619 (define_insn "udivsi3_sp32"
6620 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6621 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6622 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6624 || TARGET_DEPRECATED_V8_INSNS)
6628 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6629 switch (which_alternative)
6632 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6634 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6636 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6639 [(set_attr "length" "5")])
6641 (define_insn "udivsi3_sp64"
6642 [(set (match_operand:SI 0 "register_operand" "=r")
6643 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6644 (match_operand:SI 2 "input_operand" "rI")))]
6645 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6646 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6647 [(set_attr "length" "2")])
6649 (define_insn "udivdi3"
6650 [(set (match_operand:DI 0 "register_operand" "=r")
6651 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6652 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6654 "udivx\\t%1, %2, %0")
6656 (define_insn "*cmp_udiv_cc_set"
6658 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6659 (match_operand:SI 2 "arith_operand" "rI"))
6661 (set (match_operand:SI 0 "register_operand" "=r")
6662 (udiv:SI (match_dup 1) (match_dup 2)))]
6664 || TARGET_DEPRECATED_V8_INSNS"
6668 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6670 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6672 [(set (attr "length")
6673 (if_then_else (eq_attr "isa" "v9")
6674 (const_int 2) (const_int 5)))])
6676 ; sparclet multiply/accumulate insns
6678 (define_insn "*smacsi"
6679 [(set (match_operand:SI 0 "register_operand" "=r")
6680 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6681 (match_operand:SI 2 "arith_operand" "rI"))
6682 (match_operand:SI 3 "register_operand" "0")))]
6685 [(set_attr "type" "imul")
6686 (set_attr "length" "1")])
6688 (define_insn "*smacdi"
6689 [(set (match_operand:DI 0 "register_operand" "=r")
6690 (plus:DI (mult:DI (sign_extend:DI
6691 (match_operand:SI 1 "register_operand" "%r"))
6693 (match_operand:SI 2 "register_operand" "r")))
6694 (match_operand:DI 3 "register_operand" "0")))]
6696 "smacd\\t%1, %2, %L0"
6697 [(set_attr "type" "imul")
6698 (set_attr "length" "1")])
6700 (define_insn "*umacdi"
6701 [(set (match_operand:DI 0 "register_operand" "=r")
6702 (plus:DI (mult:DI (zero_extend:DI
6703 (match_operand:SI 1 "register_operand" "%r"))
6705 (match_operand:SI 2 "register_operand" "r")))
6706 (match_operand:DI 3 "register_operand" "0")))]
6708 "umacd\\t%1, %2, %L0"
6709 [(set_attr "type" "imul")
6710 (set_attr "length" "1")])
6712 ;;- Boolean instructions
6713 ;; We define DImode `and' so with DImode `not' we can get
6714 ;; DImode `andn'. Other combinations are possible.
6716 (define_expand "anddi3"
6717 [(set (match_operand:DI 0 "register_operand" "")
6718 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6719 (match_operand:DI 2 "arith_double_operand" "")))]
6723 (define_insn "*anddi3_sp32"
6724 [(set (match_operand:DI 0 "register_operand" "=r,b")
6725 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6726 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6731 [(set_attr "type" "ialu,fp")
6732 (set_attr "length" "2,1")])
6734 (define_insn "*anddi3_sp64"
6735 [(set (match_operand:DI 0 "register_operand" "=r,b")
6736 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6737 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6742 [(set_attr "type" "ialu,fp")
6743 (set_attr "length" "1,1")])
6745 (define_insn "andsi3"
6746 [(set (match_operand:SI 0 "register_operand" "=r,d")
6747 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6748 (match_operand:SI 2 "arith_operand" "rI,d")))]
6753 [(set_attr "type" "ialu,fp")
6754 (set_attr "length" "1,1")])
6757 [(set (match_operand:SI 0 "register_operand" "")
6758 (and:SI (match_operand:SI 1 "register_operand" "")
6759 (match_operand:SI 2 "" "")))
6760 (clobber (match_operand:SI 3 "register_operand" ""))]
6761 "GET_CODE (operands[2]) == CONST_INT
6762 && !SMALL_INT32 (operands[2])
6763 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6764 [(set (match_dup 3) (match_dup 4))
6765 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6768 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6771 ;; Split DImode logical operations requiring two instructions.
6773 [(set (match_operand:DI 0 "register_operand" "")
6774 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6775 [(match_operand:DI 2 "register_operand" "")
6776 (match_operand:DI 3 "arith_double_operand" "")]))]
6779 && ((GET_CODE (operands[0]) == REG
6780 && REGNO (operands[0]) < 32)
6781 || (GET_CODE (operands[0]) == SUBREG
6782 && GET_CODE (SUBREG_REG (operands[0])) == REG
6783 && REGNO (SUBREG_REG (operands[0])) < 32))"
6784 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6785 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6788 if (GET_CODE (operands[0]) == SUBREG)
6789 operands[0] = alter_subreg (operands[0]);
6790 operands[4] = gen_highpart (SImode, operands[0]);
6791 operands[5] = gen_lowpart (SImode, operands[0]);
6792 operands[6] = gen_highpart (SImode, operands[2]);
6793 operands[7] = gen_lowpart (SImode, operands[2]);
6794 #if HOST_BITS_PER_WIDE_INT == 32
6795 if (GET_CODE (operands[3]) == CONST_INT)
6797 if (INTVAL (operands[3]) < 0)
6798 operands[8] = constm1_rtx;
6800 operands[8] = const0_rtx;
6804 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6805 operands[9] = gen_lowpart (SImode, operands[3]);
6808 (define_insn "*and_not_di_sp32"
6809 [(set (match_operand:DI 0 "register_operand" "=r,b")
6810 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6811 (match_operand:DI 2 "register_operand" "r,b")))]
6815 fandnot1\\t%1, %2, %0"
6816 [(set_attr "type" "ialu,fp")
6817 (set_attr "length" "2,1")])
6820 [(set (match_operand:DI 0 "register_operand" "")
6821 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6822 (match_operand:DI 2 "register_operand" "")))]
6825 && ((GET_CODE (operands[0]) == REG
6826 && REGNO (operands[0]) < 32)
6827 || (GET_CODE (operands[0]) == SUBREG
6828 && GET_CODE (SUBREG_REG (operands[0])) == REG
6829 && REGNO (SUBREG_REG (operands[0])) < 32))"
6830 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6831 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6832 "if (GET_CODE (operands[0]) == SUBREG)
6833 operands[0] = alter_subreg (operands[0]);
6834 operands[3] = gen_highpart (SImode, operands[0]);
6835 operands[4] = gen_highpart (SImode, operands[1]);
6836 operands[5] = gen_highpart (SImode, operands[2]);
6837 operands[6] = gen_lowpart (SImode, operands[0]);
6838 operands[7] = gen_lowpart (SImode, operands[1]);
6839 operands[8] = gen_lowpart (SImode, operands[2]);")
6841 (define_insn "*and_not_di_sp64"
6842 [(set (match_operand:DI 0 "register_operand" "=r,b")
6843 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6844 (match_operand:DI 2 "register_operand" "r,b")))]
6848 fandnot1\\t%1, %2, %0"
6849 [(set_attr "type" "ialu,fp")
6850 (set_attr "length" "1,1")])
6852 (define_insn "*and_not_si"
6853 [(set (match_operand:SI 0 "register_operand" "=r,d")
6854 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6855 (match_operand:SI 2 "register_operand" "r,d")))]
6859 fandnot1s\\t%1, %2, %0"
6860 [(set_attr "type" "ialu,fp")
6861 (set_attr "length" "1,1")])
6863 (define_expand "iordi3"
6864 [(set (match_operand:DI 0 "register_operand" "")
6865 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6866 (match_operand:DI 2 "arith_double_operand" "")))]
6870 (define_insn "*iordi3_sp32"
6871 [(set (match_operand:DI 0 "register_operand" "=r,b")
6872 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6873 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6878 [(set_attr "type" "ialu,fp")
6879 (set_attr "length" "2,1")])
6881 (define_insn "*iordi3_sp64"
6882 [(set (match_operand:DI 0 "register_operand" "=r,b")
6883 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6884 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6889 [(set_attr "type" "ialu,fp")
6890 (set_attr "length" "1,1")])
6892 (define_insn "iorsi3"
6893 [(set (match_operand:SI 0 "register_operand" "=r,d")
6894 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6895 (match_operand:SI 2 "arith_operand" "rI,d")))]
6900 [(set_attr "type" "ialu,fp")
6901 (set_attr "length" "1,1")])
6904 [(set (match_operand:SI 0 "register_operand" "")
6905 (ior:SI (match_operand:SI 1 "register_operand" "")
6906 (match_operand:SI 2 "" "")))
6907 (clobber (match_operand:SI 3 "register_operand" ""))]
6908 "GET_CODE (operands[2]) == CONST_INT
6909 && !SMALL_INT32 (operands[2])
6910 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6911 [(set (match_dup 3) (match_dup 4))
6912 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6915 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6918 (define_insn "*or_not_di_sp32"
6919 [(set (match_operand:DI 0 "register_operand" "=r,b")
6920 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6921 (match_operand:DI 2 "register_operand" "r,b")))]
6925 fornot1\\t%1, %2, %0"
6926 [(set_attr "type" "ialu,fp")
6927 (set_attr "length" "2,1")])
6930 [(set (match_operand:DI 0 "register_operand" "")
6931 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6932 (match_operand:DI 2 "register_operand" "")))]
6935 && ((GET_CODE (operands[0]) == REG
6936 && REGNO (operands[0]) < 32)
6937 || (GET_CODE (operands[0]) == SUBREG
6938 && GET_CODE (SUBREG_REG (operands[0])) == REG
6939 && REGNO (SUBREG_REG (operands[0])) < 32))"
6940 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6941 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6942 "if (GET_CODE (operands[0]) == SUBREG)
6943 operands[0] = alter_subreg (operands[0]);
6944 operands[3] = gen_highpart (SImode, operands[0]);
6945 operands[4] = gen_highpart (SImode, operands[1]);
6946 operands[5] = gen_highpart (SImode, operands[2]);
6947 operands[6] = gen_lowpart (SImode, operands[0]);
6948 operands[7] = gen_lowpart (SImode, operands[1]);
6949 operands[8] = gen_lowpart (SImode, operands[2]);")
6951 (define_insn "*or_not_di_sp64"
6952 [(set (match_operand:DI 0 "register_operand" "=r,b")
6953 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6954 (match_operand:DI 2 "register_operand" "r,b")))]
6958 fornot1\\t%1, %2, %0"
6959 [(set_attr "type" "ialu,fp")
6960 (set_attr "length" "1,1")])
6962 (define_insn "*or_not_si"
6963 [(set (match_operand:SI 0 "register_operand" "=r,d")
6964 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6965 (match_operand:SI 2 "register_operand" "r,d")))]
6969 fornot1s\\t%1, %2, %0"
6970 [(set_attr "type" "ialu,fp")
6971 (set_attr "length" "1,1")])
6973 (define_expand "xordi3"
6974 [(set (match_operand:DI 0 "register_operand" "")
6975 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6976 (match_operand:DI 2 "arith_double_operand" "")))]
6980 (define_insn "*xordi3_sp32"
6981 [(set (match_operand:DI 0 "register_operand" "=r,b")
6982 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6983 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6988 [(set_attr "length" "2,1")
6989 (set_attr "type" "ialu,fp")])
6991 (define_insn "*xordi3_sp64"
6992 [(set (match_operand:DI 0 "register_operand" "=r,b")
6993 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6994 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6999 [(set_attr "type" "ialu,fp")
7000 (set_attr "length" "1,1")])
7002 (define_insn "*xordi3_sp64_dbl"
7003 [(set (match_operand:DI 0 "register_operand" "=r")
7004 (xor:DI (match_operand:DI 1 "register_operand" "r")
7005 (match_operand:DI 2 "const64_operand" "")))]
7007 && HOST_BITS_PER_WIDE_INT != 64)"
7009 [(set_attr "type" "ialu")
7010 (set_attr "length" "1")])
7012 (define_insn "xorsi3"
7013 [(set (match_operand:SI 0 "register_operand" "=r,d")
7014 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
7015 (match_operand:SI 2 "arith_operand" "rI,d")))]
7020 [(set_attr "type" "ialu,fp")
7021 (set_attr "length" "1,1")])
7024 [(set (match_operand:SI 0 "register_operand" "")
7025 (xor:SI (match_operand:SI 1 "register_operand" "")
7026 (match_operand:SI 2 "" "")))
7027 (clobber (match_operand:SI 3 "register_operand" ""))]
7028 "GET_CODE (operands[2]) == CONST_INT
7029 && !SMALL_INT32 (operands[2])
7030 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
7031 [(set (match_dup 3) (match_dup 4))
7032 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
7035 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
7039 [(set (match_operand:SI 0 "register_operand" "")
7040 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
7041 (match_operand:SI 2 "" ""))))
7042 (clobber (match_operand:SI 3 "register_operand" ""))]
7043 "GET_CODE (operands[2]) == CONST_INT
7044 && !SMALL_INT32 (operands[2])
7045 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
7046 [(set (match_dup 3) (match_dup 4))
7047 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
7050 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
7053 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
7054 ;; Combine now canonicalizes to the rightmost expression.
7055 (define_insn "*xor_not_di_sp32"
7056 [(set (match_operand:DI 0 "register_operand" "=r,b")
7057 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
7058 (match_operand:DI 2 "register_operand" "r,b"))))]
7063 [(set_attr "length" "2,1")
7064 (set_attr "type" "ialu,fp")])
7067 [(set (match_operand:DI 0 "register_operand" "")
7068 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
7069 (match_operand:DI 2 "register_operand" ""))))]
7072 && ((GET_CODE (operands[0]) == REG
7073 && REGNO (operands[0]) < 32)
7074 || (GET_CODE (operands[0]) == SUBREG
7075 && GET_CODE (SUBREG_REG (operands[0])) == REG
7076 && REGNO (SUBREG_REG (operands[0])) < 32))"
7077 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
7078 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
7079 "if (GET_CODE (operands[0]) == SUBREG)
7080 operands[0] = alter_subreg (operands[0]);
7081 operands[3] = gen_highpart (SImode, operands[0]);
7082 operands[4] = gen_highpart (SImode, operands[1]);
7083 operands[5] = gen_highpart (SImode, operands[2]);
7084 operands[6] = gen_lowpart (SImode, operands[0]);
7085 operands[7] = gen_lowpart (SImode, operands[1]);
7086 operands[8] = gen_lowpart (SImode, operands[2]);")
7088 (define_insn "*xor_not_di_sp64"
7089 [(set (match_operand:DI 0 "register_operand" "=r,b")
7090 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
7091 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
7096 [(set_attr "type" "ialu,fp")
7097 (set_attr "length" "1,1")])
7099 (define_insn "*xor_not_si"
7100 [(set (match_operand:SI 0 "register_operand" "=r,d")
7101 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
7102 (match_operand:SI 2 "arith_operand" "rI,d"))))]
7106 fxnors\\t%1, %2, %0"
7107 [(set_attr "type" "ialu,fp")
7108 (set_attr "length" "1,1")])
7110 ;; These correspond to the above in the case where we also (or only)
7111 ;; want to set the condition code.
7113 (define_insn "*cmp_cc_arith_op"
7116 (match_operator:SI 2 "cc_arithop"
7117 [(match_operand:SI 0 "arith_operand" "%r")
7118 (match_operand:SI 1 "arith_operand" "rI")])
7121 "%A2cc\\t%0, %1, %%g0"
7122 [(set_attr "type" "compare")
7123 (set_attr "length" "1")])
7125 (define_insn "*cmp_ccx_arith_op"
7128 (match_operator:DI 2 "cc_arithop"
7129 [(match_operand:DI 0 "arith_double_operand" "%r")
7130 (match_operand:DI 1 "arith_double_operand" "rHI")])
7133 "%A2cc\\t%0, %1, %%g0"
7134 [(set_attr "type" "compare")
7135 (set_attr "length" "1")])
7137 (define_insn "*cmp_cc_arith_op_set"
7140 (match_operator:SI 3 "cc_arithop"
7141 [(match_operand:SI 1 "arith_operand" "%r")
7142 (match_operand:SI 2 "arith_operand" "rI")])
7144 (set (match_operand:SI 0 "register_operand" "=r")
7145 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7146 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7147 "%A3cc\\t%1, %2, %0"
7148 [(set_attr "type" "compare")
7149 (set_attr "length" "1")])
7151 (define_insn "*cmp_ccx_arith_op_set"
7154 (match_operator:DI 3 "cc_arithop"
7155 [(match_operand:DI 1 "arith_double_operand" "%r")
7156 (match_operand:DI 2 "arith_double_operand" "rHI")])
7158 (set (match_operand:DI 0 "register_operand" "=r")
7159 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7160 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7161 "%A3cc\\t%1, %2, %0"
7162 [(set_attr "type" "compare")
7163 (set_attr "length" "1")])
7165 (define_insn "*cmp_cc_xor_not"
7168 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7169 (match_operand:SI 1 "arith_operand" "rI")))
7172 "xnorcc\\t%r0, %1, %%g0"
7173 [(set_attr "type" "compare")
7174 (set_attr "length" "1")])
7176 (define_insn "*cmp_ccx_xor_not"
7179 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7180 (match_operand:DI 1 "arith_double_operand" "rHI")))
7183 "xnorcc\\t%r0, %1, %%g0"
7184 [(set_attr "type" "compare")
7185 (set_attr "length" "1")])
7187 (define_insn "*cmp_cc_xor_not_set"
7190 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7191 (match_operand:SI 2 "arith_operand" "rI")))
7193 (set (match_operand:SI 0 "register_operand" "=r")
7194 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7196 "xnorcc\\t%r1, %2, %0"
7197 [(set_attr "type" "compare")
7198 (set_attr "length" "1")])
7200 (define_insn "*cmp_ccx_xor_not_set"
7203 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7204 (match_operand:DI 2 "arith_double_operand" "rHI")))
7206 (set (match_operand:DI 0 "register_operand" "=r")
7207 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7209 "xnorcc\\t%r1, %2, %0"
7210 [(set_attr "type" "compare")
7211 (set_attr "length" "1")])
7213 (define_insn "*cmp_cc_arith_op_not"
7216 (match_operator:SI 2 "cc_arithopn"
7217 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7218 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7221 "%B2cc\\t%r1, %0, %%g0"
7222 [(set_attr "type" "compare")
7223 (set_attr "length" "1")])
7225 (define_insn "*cmp_ccx_arith_op_not"
7228 (match_operator:DI 2 "cc_arithopn"
7229 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7230 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7233 "%B2cc\\t%r1, %0, %%g0"
7234 [(set_attr "type" "compare")
7235 (set_attr "length" "1")])
7237 (define_insn "*cmp_cc_arith_op_not_set"
7240 (match_operator:SI 3 "cc_arithopn"
7241 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7242 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7244 (set (match_operand:SI 0 "register_operand" "=r")
7245 (match_operator:SI 4 "cc_arithopn"
7246 [(not:SI (match_dup 1)) (match_dup 2)]))]
7247 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7248 "%B3cc\\t%r2, %1, %0"
7249 [(set_attr "type" "compare")
7250 (set_attr "length" "1")])
7252 (define_insn "*cmp_ccx_arith_op_not_set"
7255 (match_operator:DI 3 "cc_arithopn"
7256 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7257 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7259 (set (match_operand:DI 0 "register_operand" "=r")
7260 (match_operator:DI 4 "cc_arithopn"
7261 [(not:DI (match_dup 1)) (match_dup 2)]))]
7262 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7263 "%B3cc\\t%r2, %1, %0"
7264 [(set_attr "type" "compare")
7265 (set_attr "length" "1")])
7267 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7268 ;; does not know how to make it work for constants.
7270 (define_expand "negdi2"
7271 [(set (match_operand:DI 0 "register_operand" "=r")
7272 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7276 if (! TARGET_ARCH64)
7278 emit_insn (gen_rtx_PARALLEL
7281 gen_rtx_SET (VOIDmode, operand0,
7282 gen_rtx_NEG (DImode, operand1)),
7283 gen_rtx_CLOBBER (VOIDmode,
7284 gen_rtx_REG (CCmode,
7290 (define_insn "*negdi2_sp32"
7291 [(set (match_operand:DI 0 "register_operand" "=r")
7292 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7293 (clobber (reg:CC 100))]
7296 [(set_attr "type" "unary")
7297 (set_attr "length" "2")])
7300 [(set (match_operand:DI 0 "register_operand" "")
7301 (neg:DI (match_operand:DI 1 "register_operand" "")))
7302 (clobber (reg:CC 100))]
7304 && reload_completed"
7305 [(parallel [(set (reg:CC_NOOV 100)
7306 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7308 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7309 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7310 (ltu:SI (reg:CC 100) (const_int 0))))]
7311 "operands[2] = gen_highpart (SImode, operands[0]);
7312 operands[3] = gen_highpart (SImode, operands[1]);
7313 operands[4] = gen_lowpart (SImode, operands[0]);
7314 operands[5] = gen_lowpart (SImode, operands[1]);")
7316 (define_insn "*negdi2_sp64"
7317 [(set (match_operand:DI 0 "register_operand" "=r")
7318 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7320 "sub\\t%%g0, %1, %0"
7321 [(set_attr "type" "unary")
7322 (set_attr "length" "1")])
7324 (define_insn "negsi2"
7325 [(set (match_operand:SI 0 "register_operand" "=r")
7326 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7328 "sub\\t%%g0, %1, %0"
7329 [(set_attr "type" "unary")
7330 (set_attr "length" "1")])
7332 (define_insn "*cmp_cc_neg"
7333 [(set (reg:CC_NOOV 100)
7334 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7337 "subcc\\t%%g0, %0, %%g0"
7338 [(set_attr "type" "compare")
7339 (set_attr "length" "1")])
7341 (define_insn "*cmp_ccx_neg"
7342 [(set (reg:CCX_NOOV 100)
7343 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7346 "subcc\\t%%g0, %0, %%g0"
7347 [(set_attr "type" "compare")
7348 (set_attr "length" "1")])
7350 (define_insn "*cmp_cc_set_neg"
7351 [(set (reg:CC_NOOV 100)
7352 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7354 (set (match_operand:SI 0 "register_operand" "=r")
7355 (neg:SI (match_dup 1)))]
7357 "subcc\\t%%g0, %1, %0"
7358 [(set_attr "type" "compare")
7359 (set_attr "length" "1")])
7361 (define_insn "*cmp_ccx_set_neg"
7362 [(set (reg:CCX_NOOV 100)
7363 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7365 (set (match_operand:DI 0 "register_operand" "=r")
7366 (neg:DI (match_dup 1)))]
7368 "subcc\\t%%g0, %1, %0"
7369 [(set_attr "type" "compare")
7370 (set_attr "length" "1")])
7372 ;; We cannot use the "not" pseudo insn because the Sun assembler
7373 ;; does not know how to make it work for constants.
7374 (define_expand "one_cmpldi2"
7375 [(set (match_operand:DI 0 "register_operand" "")
7376 (not:DI (match_operand:DI 1 "register_operand" "")))]
7380 (define_insn "*one_cmpldi2_sp32"
7381 [(set (match_operand:DI 0 "register_operand" "=r,b")
7382 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7387 [(set_attr "type" "unary,fp")
7388 (set_attr "length" "2,1")])
7391 [(set (match_operand:DI 0 "register_operand" "")
7392 (not:DI (match_operand:DI 1 "register_operand" "")))]
7395 && ((GET_CODE (operands[0]) == REG
7396 && REGNO (operands[0]) < 32)
7397 || (GET_CODE (operands[0]) == SUBREG
7398 && GET_CODE (SUBREG_REG (operands[0])) == REG
7399 && REGNO (SUBREG_REG (operands[0])) < 32))"
7400 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7401 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7402 "if (GET_CODE (operands[0]) == SUBREG)
7403 operands[0] = alter_subreg (operands[0]);
7404 operands[2] = gen_highpart (SImode, operands[0]);
7405 operands[3] = gen_highpart (SImode, operands[1]);
7406 operands[4] = gen_lowpart (SImode, operands[0]);
7407 operands[5] = gen_lowpart (SImode, operands[1]);")
7409 (define_insn "*one_cmpldi2_sp64"
7410 [(set (match_operand:DI 0 "register_operand" "=r,b")
7411 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7416 [(set_attr "type" "unary,fp")
7417 (set_attr "length" "1")])
7419 (define_insn "one_cmplsi2"
7420 [(set (match_operand:SI 0 "register_operand" "=r,d")
7421 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7426 [(set_attr "type" "unary,fp")
7427 (set_attr "length" "1,1")])
7429 (define_insn "*cmp_cc_not"
7431 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7434 "xnorcc\\t%%g0, %0, %%g0"
7435 [(set_attr "type" "compare")
7436 (set_attr "length" "1")])
7438 (define_insn "*cmp_ccx_not"
7440 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7443 "xnorcc\\t%%g0, %0, %%g0"
7444 [(set_attr "type" "compare")
7445 (set_attr "length" "1")])
7447 (define_insn "*cmp_cc_set_not"
7449 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7451 (set (match_operand:SI 0 "register_operand" "=r")
7452 (not:SI (match_dup 1)))]
7454 "xnorcc\\t%%g0, %1, %0"
7455 [(set_attr "type" "compare")
7456 (set_attr "length" "1")])
7458 (define_insn "*cmp_ccx_set_not"
7460 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7462 (set (match_operand:DI 0 "register_operand" "=r")
7463 (not:DI (match_dup 1)))]
7465 "xnorcc\\t%%g0, %1, %0"
7466 [(set_attr "type" "compare")
7467 (set_attr "length" "1")])
7469 ;; Floating point arithmetic instructions.
7471 (define_expand "addtf3"
7472 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7473 (plus:TF (match_operand:TF 1 "general_operand" "")
7474 (match_operand:TF 2 "general_operand" "")))]
7475 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7478 if (! TARGET_HARD_QUAD)
7480 rtx slot0, slot1, slot2;
7482 if (GET_CODE (operands[0]) != MEM)
7483 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7485 slot0 = operands[0];
7486 if (GET_CODE (operands[1]) != MEM)
7488 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7489 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7492 slot1 = operands[1];
7493 if (GET_CODE (operands[2]) != MEM)
7495 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7496 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7499 slot2 = operands[2];
7501 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7503 XEXP (slot0, 0), Pmode,
7504 XEXP (slot1, 0), Pmode,
7505 XEXP (slot2, 0), Pmode);
7507 if (GET_CODE (operands[0]) != MEM)
7508 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7513 (define_insn "*addtf3_hq"
7514 [(set (match_operand:TF 0 "register_operand" "=e")
7515 (plus:TF (match_operand:TF 1 "register_operand" "e")
7516 (match_operand:TF 2 "register_operand" "e")))]
7517 "TARGET_FPU && TARGET_HARD_QUAD"
7518 "faddq\\t%1, %2, %0"
7519 [(set_attr "type" "fp")
7520 (set_attr "length" "1")])
7522 (define_insn "adddf3"
7523 [(set (match_operand:DF 0 "register_operand" "=e")
7524 (plus:DF (match_operand:DF 1 "register_operand" "e")
7525 (match_operand:DF 2 "register_operand" "e")))]
7527 "faddd\\t%1, %2, %0"
7528 [(set_attr "type" "fp")
7529 (set_attr "length" "1")])
7531 (define_insn "addsf3"
7532 [(set (match_operand:SF 0 "register_operand" "=f")
7533 (plus:SF (match_operand:SF 1 "register_operand" "f")
7534 (match_operand:SF 2 "register_operand" "f")))]
7536 "fadds\\t%1, %2, %0"
7537 [(set_attr "type" "fp")
7538 (set_attr "length" "1")])
7540 (define_expand "subtf3"
7541 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7542 (minus:TF (match_operand:TF 1 "general_operand" "")
7543 (match_operand:TF 2 "general_operand" "")))]
7544 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7547 if (! TARGET_HARD_QUAD)
7549 rtx slot0, slot1, slot2;
7551 if (GET_CODE (operands[0]) != MEM)
7552 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7554 slot0 = operands[0];
7555 if (GET_CODE (operands[1]) != MEM)
7557 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7558 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7561 slot1 = operands[1];
7562 if (GET_CODE (operands[2]) != MEM)
7564 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7565 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7568 slot2 = operands[2];
7570 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7572 XEXP (slot0, 0), Pmode,
7573 XEXP (slot1, 0), Pmode,
7574 XEXP (slot2, 0), Pmode);
7576 if (GET_CODE (operands[0]) != MEM)
7577 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7582 (define_insn "*subtf3_hq"
7583 [(set (match_operand:TF 0 "register_operand" "=e")
7584 (minus:TF (match_operand:TF 1 "register_operand" "e")
7585 (match_operand:TF 2 "register_operand" "e")))]
7586 "TARGET_FPU && TARGET_HARD_QUAD"
7587 "fsubq\\t%1, %2, %0"
7588 [(set_attr "type" "fp")
7589 (set_attr "length" "1")])
7591 (define_insn "subdf3"
7592 [(set (match_operand:DF 0 "register_operand" "=e")
7593 (minus:DF (match_operand:DF 1 "register_operand" "e")
7594 (match_operand:DF 2 "register_operand" "e")))]
7596 "fsubd\\t%1, %2, %0"
7597 [(set_attr "type" "fp")
7598 (set_attr "length" "1")])
7600 (define_insn "subsf3"
7601 [(set (match_operand:SF 0 "register_operand" "=f")
7602 (minus:SF (match_operand:SF 1 "register_operand" "f")
7603 (match_operand:SF 2 "register_operand" "f")))]
7605 "fsubs\\t%1, %2, %0"
7606 [(set_attr "type" "fp")
7607 (set_attr "length" "1")])
7609 (define_expand "multf3"
7610 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7611 (mult:TF (match_operand:TF 1 "general_operand" "")
7612 (match_operand:TF 2 "general_operand" "")))]
7613 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7616 if (! TARGET_HARD_QUAD)
7618 rtx slot0, slot1, slot2;
7620 if (GET_CODE (operands[0]) != MEM)
7621 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7623 slot0 = operands[0];
7624 if (GET_CODE (operands[1]) != MEM)
7626 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7627 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7630 slot1 = operands[1];
7631 if (GET_CODE (operands[2]) != MEM)
7633 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7634 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7637 slot2 = operands[2];
7639 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7641 XEXP (slot0, 0), Pmode,
7642 XEXP (slot1, 0), Pmode,
7643 XEXP (slot2, 0), Pmode);
7645 if (GET_CODE (operands[0]) != MEM)
7646 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7651 (define_insn "*multf3_hq"
7652 [(set (match_operand:TF 0 "register_operand" "=e")
7653 (mult:TF (match_operand:TF 1 "register_operand" "e")
7654 (match_operand:TF 2 "register_operand" "e")))]
7655 "TARGET_FPU && TARGET_HARD_QUAD"
7656 "fmulq\\t%1, %2, %0"
7657 [(set_attr "type" "fpmul")
7658 (set_attr "length" "1")])
7660 (define_insn "muldf3"
7661 [(set (match_operand:DF 0 "register_operand" "=e")
7662 (mult:DF (match_operand:DF 1 "register_operand" "e")
7663 (match_operand:DF 2 "register_operand" "e")))]
7665 "fmuld\\t%1, %2, %0"
7666 [(set_attr "type" "fpmul")
7667 (set_attr "length" "1")])
7669 (define_insn "mulsf3"
7670 [(set (match_operand:SF 0 "register_operand" "=f")
7671 (mult:SF (match_operand:SF 1 "register_operand" "f")
7672 (match_operand:SF 2 "register_operand" "f")))]
7674 "fmuls\\t%1, %2, %0"
7675 [(set_attr "type" "fpmul")
7676 (set_attr "length" "1")])
7678 (define_insn "*muldf3_extend"
7679 [(set (match_operand:DF 0 "register_operand" "=e")
7680 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7681 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7682 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7683 "fsmuld\\t%1, %2, %0"
7684 [(set_attr "type" "fpmul")
7685 (set_attr "length" "1")])
7687 (define_insn "*multf3_extend"
7688 [(set (match_operand:TF 0 "register_operand" "=e")
7689 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7690 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7691 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7692 "fdmulq\\t%1, %2, %0"
7693 [(set_attr "type" "fpmul")
7694 (set_attr "length" "1")])
7696 (define_expand "divtf3"
7697 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7698 (div:TF (match_operand:TF 1 "general_operand" "")
7699 (match_operand:TF 2 "general_operand" "")))]
7700 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7703 if (! TARGET_HARD_QUAD)
7705 rtx slot0, slot1, slot2;
7707 if (GET_CODE (operands[0]) != MEM)
7708 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7710 slot0 = operands[0];
7711 if (GET_CODE (operands[1]) != MEM)
7713 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7714 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7717 slot1 = operands[1];
7718 if (GET_CODE (operands[2]) != MEM)
7720 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7721 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7724 slot2 = operands[2];
7726 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7728 XEXP (slot0, 0), Pmode,
7729 XEXP (slot1, 0), Pmode,
7730 XEXP (slot2, 0), Pmode);
7732 if (GET_CODE (operands[0]) != MEM)
7733 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7738 ;; don't have timing for quad-prec. divide.
7739 (define_insn "*divtf3_hq"
7740 [(set (match_operand:TF 0 "register_operand" "=e")
7741 (div:TF (match_operand:TF 1 "register_operand" "e")
7742 (match_operand:TF 2 "register_operand" "e")))]
7743 "TARGET_FPU && TARGET_HARD_QUAD"
7744 "fdivq\\t%1, %2, %0"
7745 [(set_attr "type" "fpdivd")
7746 (set_attr "length" "1")])
7748 (define_insn "divdf3"
7749 [(set (match_operand:DF 0 "register_operand" "=e")
7750 (div:DF (match_operand:DF 1 "register_operand" "e")
7751 (match_operand:DF 2 "register_operand" "e")))]
7753 "fdivd\\t%1, %2, %0"
7754 [(set_attr "type" "fpdivd")
7755 (set_attr "length" "1")])
7757 (define_insn "divsf3"
7758 [(set (match_operand:SF 0 "register_operand" "=f")
7759 (div:SF (match_operand:SF 1 "register_operand" "f")
7760 (match_operand:SF 2 "register_operand" "f")))]
7762 "fdivs\\t%1, %2, %0"
7763 [(set_attr "type" "fpdivs")
7764 (set_attr "length" "1")])
7766 (define_expand "negtf2"
7767 [(set (match_operand:TF 0 "register_operand" "=e,e")
7768 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7772 (define_insn "*negtf2_notv9"
7773 [(set (match_operand:TF 0 "register_operand" "=e,e")
7774 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7775 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7781 [(set_attr "type" "fpmove")
7782 (set_attr "length" "1,2")])
7785 [(set (match_operand:TF 0 "register_operand" "")
7786 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7790 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7791 [(set (match_dup 2) (neg:SF (match_dup 3)))
7792 (set (match_dup 4) (match_dup 5))
7793 (set (match_dup 6) (match_dup 7))]
7794 "if (GET_CODE (operands[0]) == SUBREG)
7795 operands[0] = alter_subreg (operands[0]);
7796 if (GET_CODE (operands[1]) == SUBREG)
7797 operands[1] = alter_subreg (operands[1]);
7798 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7799 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7800 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7801 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7802 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7803 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7805 (define_insn "*negtf2_v9"
7806 [(set (match_operand:TF 0 "register_operand" "=e,e")
7807 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7808 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7809 "TARGET_FPU && TARGET_V9"
7813 [(set_attr "type" "fpmove")
7814 (set_attr "length" "1,2")])
7817 [(set (match_operand:TF 0 "register_operand" "")
7818 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7822 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7823 [(set (match_dup 2) (neg:DF (match_dup 3)))
7824 (set (match_dup 4) (match_dup 5))]
7825 "if (GET_CODE (operands[0]) == SUBREG)
7826 operands[0] = alter_subreg (operands[0]);
7827 if (GET_CODE (operands[1]) == SUBREG)
7828 operands[1] = alter_subreg (operands[1]);
7829 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7830 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7831 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7832 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7834 (define_expand "negdf2"
7835 [(set (match_operand:DF 0 "register_operand" "")
7836 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7840 (define_insn "*negdf2_notv9"
7841 [(set (match_operand:DF 0 "register_operand" "=e,e")
7842 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7843 "TARGET_FPU && ! TARGET_V9"
7847 [(set_attr "type" "fpmove")
7848 (set_attr "length" "1,2")])
7851 [(set (match_operand:DF 0 "register_operand" "")
7852 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7856 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7857 [(set (match_dup 2) (neg:SF (match_dup 3)))
7858 (set (match_dup 4) (match_dup 5))]
7859 "if (GET_CODE (operands[0]) == SUBREG)
7860 operands[0] = alter_subreg (operands[0]);
7861 if (GET_CODE (operands[1]) == SUBREG)
7862 operands[1] = alter_subreg (operands[1]);
7863 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7864 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7865 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7866 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7868 (define_insn "*negdf2_v9"
7869 [(set (match_operand:DF 0 "register_operand" "=e")
7870 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7871 "TARGET_FPU && TARGET_V9"
7873 [(set_attr "type" "fpmove")
7874 (set_attr "length" "1")])
7876 (define_insn "negsf2"
7877 [(set (match_operand:SF 0 "register_operand" "=f")
7878 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7881 [(set_attr "type" "fpmove")
7882 (set_attr "length" "1")])
7884 (define_expand "abstf2"
7885 [(set (match_operand:TF 0 "register_operand" "")
7886 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7890 (define_insn "*abstf2_notv9"
7891 [(set (match_operand:TF 0 "register_operand" "=e,e")
7892 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7893 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7894 "TARGET_FPU && ! TARGET_V9"
7898 [(set_attr "type" "fpmove")
7899 (set_attr "length" "1,2")])
7902 [(set (match_operand:TF 0 "register_operand" "=e,e")
7903 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7907 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7908 [(set (match_dup 2) (abs:SF (match_dup 3)))
7909 (set (match_dup 4) (match_dup 5))
7910 (set (match_dup 6) (match_dup 7))]
7911 "if (GET_CODE (operands[0]) == SUBREG)
7912 operands[0] = alter_subreg (operands[0]);
7913 if (GET_CODE (operands[1]) == SUBREG)
7914 operands[1] = alter_subreg (operands[1]);
7915 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7916 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7917 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7918 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7919 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7920 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7922 (define_insn "*abstf2_hq_v9"
7923 [(set (match_operand:TF 0 "register_operand" "=e,e")
7924 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7925 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7929 [(set_attr "type" "fpmove")
7930 (set_attr "length" "1")])
7932 (define_insn "*abstf2_v9"
7933 [(set (match_operand:TF 0 "register_operand" "=e,e")
7934 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7935 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7939 [(set_attr "type" "fpmove")
7940 (set_attr "length" "1,2")])
7943 [(set (match_operand:TF 0 "register_operand" "=e,e")
7944 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7948 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7949 [(set (match_dup 2) (abs:DF (match_dup 3)))
7950 (set (match_dup 4) (match_dup 5))]
7951 "if (GET_CODE (operands[0]) == SUBREG)
7952 operands[0] = alter_subreg (operands[0]);
7953 if (GET_CODE (operands[1]) == SUBREG)
7954 operands[1] = alter_subreg (operands[1]);
7955 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7956 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7957 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7958 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7960 (define_expand "absdf2"
7961 [(set (match_operand:DF 0 "register_operand" "")
7962 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7966 (define_insn "*absdf2_notv9"
7967 [(set (match_operand:DF 0 "register_operand" "=e,e")
7968 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7969 "TARGET_FPU && ! TARGET_V9"
7973 [(set_attr "type" "fpmove")
7974 (set_attr "length" "1,2")])
7977 [(set (match_operand:DF 0 "register_operand" "=e,e")
7978 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7982 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7983 [(set (match_dup 2) (abs:SF (match_dup 3)))
7984 (set (match_dup 4) (match_dup 5))]
7985 "if (GET_CODE (operands[0]) == SUBREG)
7986 operands[0] = alter_subreg (operands[0]);
7987 if (GET_CODE (operands[1]) == SUBREG)
7988 operands[1] = alter_subreg (operands[1]);
7989 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7990 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7991 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7992 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7994 (define_insn "*absdf2_v9"
7995 [(set (match_operand:DF 0 "register_operand" "=e")
7996 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7997 "TARGET_FPU && TARGET_V9"
7999 [(set_attr "type" "fpmove")
8000 (set_attr "length" "1")])
8002 (define_insn "abssf2"
8003 [(set (match_operand:SF 0 "register_operand" "=f")
8004 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
8007 [(set_attr "type" "fpmove")
8008 (set_attr "length" "1")])
8010 (define_expand "sqrttf2"
8011 [(set (match_operand:TF 0 "register_operand" "=e")
8012 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
8013 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
8016 if (! TARGET_HARD_QUAD)
8020 if (GET_CODE (operands[0]) != MEM)
8021 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
8023 slot0 = operands[0];
8024 if (GET_CODE (operands[1]) != MEM)
8026 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
8027 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
8030 slot1 = operands[1];
8032 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
8034 XEXP (slot0, 0), Pmode,
8035 XEXP (slot1, 0), Pmode);
8037 if (GET_CODE (operands[0]) != MEM)
8038 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
8043 (define_insn "*sqrttf2_hq"
8044 [(set (match_operand:TF 0 "register_operand" "=e")
8045 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
8046 "TARGET_FPU && TARGET_HARD_QUAD"
8048 [(set_attr "type" "fpsqrtd")
8049 (set_attr "length" "1")])
8051 (define_insn "sqrtdf2"
8052 [(set (match_operand:DF 0 "register_operand" "=e")
8053 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
8056 [(set_attr "type" "fpsqrtd")
8057 (set_attr "length" "1")])
8059 (define_insn "sqrtsf2"
8060 [(set (match_operand:SF 0 "register_operand" "=f")
8061 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
8064 [(set_attr "type" "fpsqrts")
8065 (set_attr "length" "1")])
8067 ;;- arithmetic shift instructions
8069 (define_insn "ashlsi3"
8070 [(set (match_operand:SI 0 "register_operand" "=r")
8071 (ashift:SI (match_operand:SI 1 "register_operand" "r")
8072 (match_operand:SI 2 "arith_operand" "rI")))]
8076 if (GET_CODE (operands[2]) == CONST_INT
8077 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8078 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8080 return \"sll\\t%1, %2, %0\";
8082 [(set_attr "type" "shift")
8083 (set_attr "length" "1")])
8085 ;; We special case multiplication by two, as add can be done
8086 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8087 (define_insn "*ashlsi3_const1"
8088 [(set (match_operand:SI 0 "register_operand" "=r")
8089 (ashift:SI (match_operand:SI 1 "register_operand" "r")
8093 [(set_attr "type" "binary")
8094 (set_attr "length" "1")])
8096 (define_expand "ashldi3"
8097 [(set (match_operand:DI 0 "register_operand" "=r")
8098 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8099 (match_operand:SI 2 "arith_operand" "rI")))]
8100 "TARGET_ARCH64 || TARGET_V8PLUS"
8103 if (! TARGET_ARCH64)
8105 if (GET_CODE (operands[2]) == CONST_INT)
8107 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
8112 ;; We special case multiplication by two, as add can be done
8113 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8114 (define_insn "*ashldi3_const1"
8115 [(set (match_operand:DI 0 "register_operand" "=r")
8116 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8120 [(set_attr "type" "binary")
8121 (set_attr "length" "1")])
8123 (define_insn "*ashldi3_sp64"
8124 [(set (match_operand:DI 0 "register_operand" "=r")
8125 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8126 (match_operand:SI 2 "arith_operand" "rI")))]
8130 if (GET_CODE (operands[2]) == CONST_INT
8131 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8132 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8134 return \"sllx\\t%1, %2, %0\";
8136 [(set_attr "type" "shift")
8137 (set_attr "length" "1")])
8140 (define_insn "ashldi3_v8plus"
8141 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8142 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8143 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8144 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8146 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
8147 [(set_attr "length" "5,5,6")])
8149 ;; Optimize (1LL<<x)-1
8150 ;; XXX this also needs to be fixed to handle equal subregs
8151 ;; XXX first before we could re-enable it.
8153 ; [(set (match_operand:DI 0 "register_operand" "=h")
8154 ; (plus:DI (ashift:DI (const_int 1)
8155 ; (match_operand:SI 1 "arith_operand" "rI"))
8157 ; "0 && TARGET_V8PLUS"
8160 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
8161 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8162 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8164 ; [(set_attr "length" "4")])
8166 (define_insn "*cmp_cc_ashift_1"
8167 [(set (reg:CC_NOOV 100)
8168 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8172 "addcc\\t%0, %0, %%g0"
8173 [(set_attr "type" "compare")
8174 (set_attr "length" "1")])
8176 (define_insn "*cmp_cc_set_ashift_1"
8177 [(set (reg:CC_NOOV 100)
8178 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8181 (set (match_operand:SI 0 "register_operand" "=r")
8182 (ashift:SI (match_dup 1) (const_int 1)))]
8184 "addcc\\t%1, %1, %0"
8185 [(set_attr "type" "compare")
8186 (set_attr "length" "1")])
8188 (define_insn "ashrsi3"
8189 [(set (match_operand:SI 0 "register_operand" "=r")
8190 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8191 (match_operand:SI 2 "arith_operand" "rI")))]
8195 if (GET_CODE (operands[2]) == CONST_INT
8196 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8197 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8199 return \"sra\\t%1, %2, %0\";
8201 [(set_attr "type" "shift")
8202 (set_attr "length" "1")])
8204 (define_insn "*ashrsi3_extend"
8205 [(set (match_operand:DI 0 "register_operand" "=r")
8206 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8207 (match_operand:SI 2 "arith_operand" "r"))))]
8210 [(set_attr "type" "shift")
8211 (set_attr "length" "1")])
8213 ;; This handles the case as above, but with constant shift instead of
8214 ;; register. Combiner "simplifies" it for us a little bit though.
8215 (define_insn "*ashrsi3_extend2"
8216 [(set (match_operand:DI 0 "register_operand" "=r")
8217 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8219 (match_operand:SI 2 "small_int_or_double" "n")))]
8221 && ((GET_CODE (operands[2]) == CONST_INT
8222 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8223 || (GET_CODE (operands[2]) == CONST_DOUBLE
8224 && !CONST_DOUBLE_HIGH (operands[2])
8225 && CONST_DOUBLE_LOW (operands[2]) >= 32
8226 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8229 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8231 return \"sra\\t%1, %2, %0\";
8233 [(set_attr "type" "shift")
8234 (set_attr "length" "1")])
8236 (define_expand "ashrdi3"
8237 [(set (match_operand:DI 0 "register_operand" "=r")
8238 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8239 (match_operand:SI 2 "arith_operand" "rI")))]
8240 "TARGET_ARCH64 || TARGET_V8PLUS"
8243 if (! TARGET_ARCH64)
8245 if (GET_CODE (operands[2]) == CONST_INT)
8246 FAIL; /* prefer generic code in this case */
8247 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8253 [(set (match_operand:DI 0 "register_operand" "=r")
8254 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8255 (match_operand:SI 2 "arith_operand" "rI")))]
8259 if (GET_CODE (operands[2]) == CONST_INT
8260 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8261 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8263 return \"srax\\t%1, %2, %0\";
8265 [(set_attr "type" "shift")
8266 (set_attr "length" "1")])
8269 (define_insn "ashrdi3_v8plus"
8270 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8271 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8272 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8273 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8275 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8276 [(set_attr "length" "5,5,6")])
8278 (define_insn "lshrsi3"
8279 [(set (match_operand:SI 0 "register_operand" "=r")
8280 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8281 (match_operand:SI 2 "arith_operand" "rI")))]
8285 if (GET_CODE (operands[2]) == CONST_INT
8286 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8287 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8289 return \"srl\\t%1, %2, %0\";
8291 [(set_attr "type" "shift")
8292 (set_attr "length" "1")])
8294 ;; This handles the case where
8295 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8296 ;; but combiner "simplifies" it for us.
8297 (define_insn "*lshrsi3_extend"
8298 [(set (match_operand:DI 0 "register_operand" "=r")
8299 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8300 (match_operand:SI 2 "arith_operand" "r")) 0)
8301 (match_operand 3 "" "")))]
8303 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8304 && CONST_DOUBLE_HIGH (operands[3]) == 0
8305 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8306 || (HOST_BITS_PER_WIDE_INT >= 64
8307 && GET_CODE (operands[3]) == CONST_INT
8308 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8310 [(set_attr "type" "shift")
8311 (set_attr "length" "1")])
8313 ;; This handles the case where
8314 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8315 ;; but combiner "simplifies" it for us.
8316 (define_insn "*lshrsi3_extend2"
8317 [(set (match_operand:DI 0 "register_operand" "=r")
8318 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8319 (match_operand 2 "small_int_or_double" "n")
8322 && ((GET_CODE (operands[2]) == CONST_INT
8323 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8324 || (GET_CODE (operands[2]) == CONST_DOUBLE
8325 && CONST_DOUBLE_HIGH (operands[2]) == 0
8326 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8329 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8331 return \"srl\\t%1, %2, %0\";
8333 [(set_attr "type" "shift")
8334 (set_attr "length" "1")])
8336 (define_expand "lshrdi3"
8337 [(set (match_operand:DI 0 "register_operand" "=r")
8338 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8339 (match_operand:SI 2 "arith_operand" "rI")))]
8340 "TARGET_ARCH64 || TARGET_V8PLUS"
8343 if (! TARGET_ARCH64)
8345 if (GET_CODE (operands[2]) == CONST_INT)
8347 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8353 [(set (match_operand:DI 0 "register_operand" "=r")
8354 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8355 (match_operand:SI 2 "arith_operand" "rI")))]
8359 if (GET_CODE (operands[2]) == CONST_INT
8360 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8361 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8363 return \"srlx\\t%1, %2, %0\";
8365 [(set_attr "type" "shift")
8366 (set_attr "length" "1")])
8369 (define_insn "lshrdi3_v8plus"
8370 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8371 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8372 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8373 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8375 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8376 [(set_attr "length" "5,5,6")])
8379 [(set (match_operand:SI 0 "register_operand" "=r")
8380 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8382 (match_operand:SI 2 "small_int_or_double" "n")))]
8384 && ((GET_CODE (operands[2]) == CONST_INT
8385 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8386 || (GET_CODE (operands[2]) == CONST_DOUBLE
8387 && !CONST_DOUBLE_HIGH (operands[2])
8388 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8391 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8393 return \"srax\\t%1, %2, %0\";
8395 [(set_attr "type" "shift")
8396 (set_attr "length" "1")])
8399 [(set (match_operand:SI 0 "register_operand" "=r")
8400 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8402 (match_operand:SI 2 "small_int_or_double" "n")))]
8404 && ((GET_CODE (operands[2]) == CONST_INT
8405 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8406 || (GET_CODE (operands[2]) == CONST_DOUBLE
8407 && !CONST_DOUBLE_HIGH (operands[2])
8408 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8411 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8413 return \"srlx\\t%1, %2, %0\";
8415 [(set_attr "type" "shift")
8416 (set_attr "length" "1")])
8419 [(set (match_operand:SI 0 "register_operand" "=r")
8420 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8421 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8422 (match_operand:SI 3 "small_int_or_double" "n")))]
8424 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8425 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8426 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8427 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8430 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8432 return \"srax\\t%1, %2, %0\";
8434 [(set_attr "type" "shift")
8435 (set_attr "length" "1")])
8438 [(set (match_operand:SI 0 "register_operand" "=r")
8439 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8440 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8441 (match_operand:SI 3 "small_int_or_double" "n")))]
8443 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8444 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8445 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8446 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8449 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8451 return \"srlx\\t%1, %2, %0\";
8453 [(set_attr "type" "shift")
8454 (set_attr "length" "1")])
8456 ;; Unconditional and other jump instructions
8457 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8458 ;; following insn is never executed. This saves us a nop. Dbx does not
8459 ;; handle such branches though, so we only use them when optimizing.
8461 [(set (pc) (label_ref (match_operand 0 "" "")))]
8465 /* TurboSparc is reported to have problems with
8468 i.e. an empty loop with the annul bit set. The workaround is to use
8472 if (! TARGET_V9 && flag_delayed_branch
8473 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8474 == INSN_ADDRESSES (INSN_UID (insn))))
8475 return \"b\\t%l0%#\";
8477 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8479 [(set_attr "type" "uncond_branch")])
8481 (define_expand "tablejump"
8482 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8483 (use (label_ref (match_operand 1 "" "")))])]
8487 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8490 /* In pic mode, our address differences are against the base of the
8491 table. Add that base value back in; CSE ought to be able to combine
8492 the two address loads. */
8496 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8498 if (CASE_VECTOR_MODE != Pmode)
8499 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8500 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8501 operands[0] = memory_address (Pmode, tmp);
8505 (define_insn "*tablejump_sp32"
8506 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8507 (use (label_ref (match_operand 1 "" "")))]
8510 [(set_attr "type" "uncond_branch")])
8512 (define_insn "*tablejump_sp64"
8513 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8514 (use (label_ref (match_operand 1 "" "")))]
8517 [(set_attr "type" "uncond_branch")])
8519 ;; This pattern recognizes the "instruction" that appears in
8520 ;; a function call that wants a structure value,
8521 ;; to inform the called function if compiled with Sun CC.
8522 ;(define_insn "*unimp_insn"
8523 ; [(match_operand:SI 0 "immediate_operand" "")]
8524 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8526 ; [(set_attr "type" "marker")])
8528 ;;- jump to subroutine
8529 (define_expand "call"
8530 ;; Note that this expression is not used for generating RTL.
8531 ;; All the RTL is generated explicitly below.
8532 [(call (match_operand 0 "call_operand" "")
8533 (match_operand 3 "" "i"))]
8534 ;; operands[2] is next_arg_register
8535 ;; operands[3] is struct_value_size_rtx.
8539 rtx fn_rtx, nregs_rtx;
8541 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8544 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8546 /* This is really a PIC sequence. We want to represent
8547 it as a funny jump so its delay slots can be filled.
8549 ??? But if this really *is* a CALL, will not it clobber the
8550 call-clobbered registers? We lose this if it is a JUMP_INSN.
8551 Why cannot we have delay slots filled if it were a CALL? */
8553 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8558 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8560 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8566 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8567 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8571 fn_rtx = operands[0];
8573 /* Count the number of parameter registers being used by this call.
8574 if that argument is NULL, it means we are using them all, which
8575 means 6 on the sparc. */
8578 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8580 nregs_rtx = GEN_INT (6);
8582 nregs_rtx = const0_rtx;
8585 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8589 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8591 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8596 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8597 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8601 /* If this call wants a structure value,
8602 emit an unimp insn to let the called function know about this. */
8603 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8605 rtx insn = emit_insn (operands[3]);
8606 SCHED_GROUP_P (insn) = 1;
8613 ;; We can't use the same pattern for these two insns, because then registers
8614 ;; in the address may not be properly reloaded.
8616 (define_insn "*call_address_sp32"
8617 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8618 (match_operand 1 "" ""))
8619 (clobber (reg:SI 15))]
8620 ;;- Do not use operand 1 for most machines.
8623 [(set_attr "type" "call")])
8625 (define_insn "*call_symbolic_sp32"
8626 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8627 (match_operand 1 "" ""))
8628 (clobber (reg:SI 15))]
8629 ;;- Do not use operand 1 for most machines.
8632 [(set_attr "type" "call")])
8634 (define_insn "*call_address_sp64"
8635 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8636 (match_operand 1 "" ""))
8637 (clobber (reg:DI 15))]
8638 ;;- Do not use operand 1 for most machines.
8641 [(set_attr "type" "call")])
8643 (define_insn "*call_symbolic_sp64"
8644 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8645 (match_operand 1 "" ""))
8646 (clobber (reg:DI 15))]
8647 ;;- Do not use operand 1 for most machines.
8650 [(set_attr "type" "call")])
8652 ;; This is a call that wants a structure value.
8653 ;; There is no such critter for v9 (??? we may need one anyway).
8654 (define_insn "*call_address_struct_value_sp32"
8655 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8656 (match_operand 1 "" ""))
8657 (match_operand 2 "immediate_operand" "")
8658 (clobber (reg:SI 15))]
8659 ;;- Do not use operand 1 for most machines.
8660 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8661 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8662 [(set_attr "type" "call_no_delay_slot")])
8664 ;; This is a call that wants a structure value.
8665 ;; There is no such critter for v9 (??? we may need one anyway).
8666 (define_insn "*call_symbolic_struct_value_sp32"
8667 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8668 (match_operand 1 "" ""))
8669 (match_operand 2 "immediate_operand" "")
8670 (clobber (reg:SI 15))]
8671 ;;- Do not use operand 1 for most machines.
8672 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8673 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8674 [(set_attr "type" "call_no_delay_slot")])
8676 ;; This is a call that may want a structure value. This is used for
8678 (define_insn "*call_address_untyped_struct_value_sp32"
8679 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8680 (match_operand 1 "" ""))
8681 (match_operand 2 "immediate_operand" "")
8682 (clobber (reg:SI 15))]
8683 ;;- Do not use operand 1 for most machines.
8684 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8685 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8686 [(set_attr "type" "call_no_delay_slot")])
8688 ;; This is a call that wants a structure value.
8689 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8690 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8691 (match_operand 1 "" ""))
8692 (match_operand 2 "immediate_operand" "")
8693 (clobber (reg:SI 15))]
8694 ;;- Do not use operand 1 for most machines.
8695 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8696 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8697 [(set_attr "type" "call_no_delay_slot")])
8699 (define_expand "call_value"
8700 ;; Note that this expression is not used for generating RTL.
8701 ;; All the RTL is generated explicitly below.
8702 [(set (match_operand 0 "register_operand" "=rf")
8703 (call (match_operand 1 "" "")
8704 (match_operand 4 "" "")))]
8705 ;; operand 2 is stack_size_rtx
8706 ;; operand 3 is next_arg_register
8710 rtx fn_rtx, nregs_rtx;
8713 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8716 fn_rtx = operands[1];
8720 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8722 nregs_rtx = GEN_INT (6);
8724 nregs_rtx = const0_rtx;
8728 gen_rtx_SET (VOIDmode, operands[0],
8729 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8730 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8732 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8737 (define_insn "*call_value_address_sp32"
8738 [(set (match_operand 0 "" "=rf")
8739 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8740 (match_operand 2 "" "")))
8741 (clobber (reg:SI 15))]
8742 ;;- Do not use operand 2 for most machines.
8745 [(set_attr "type" "call")])
8747 (define_insn "*call_value_symbolic_sp32"
8748 [(set (match_operand 0 "" "=rf")
8749 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8750 (match_operand 2 "" "")))
8751 (clobber (reg:SI 15))]
8752 ;;- Do not use operand 2 for most machines.
8755 [(set_attr "type" "call")])
8757 (define_insn "*call_value_address_sp64"
8758 [(set (match_operand 0 "" "")
8759 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8760 (match_operand 2 "" "")))
8761 (clobber (reg:DI 15))]
8762 ;;- Do not use operand 2 for most machines.
8765 [(set_attr "type" "call")])
8767 (define_insn "*call_value_symbolic_sp64"
8768 [(set (match_operand 0 "" "")
8769 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8770 (match_operand 2 "" "")))
8771 (clobber (reg:DI 15))]
8772 ;;- Do not use operand 2 for most machines.
8775 [(set_attr "type" "call")])
8777 (define_expand "untyped_call"
8778 [(parallel [(call (match_operand 0 "" "")
8780 (match_operand 1 "" "")
8781 (match_operand 2 "" "")])]
8787 /* Pass constm1 to indicate that it may expect a structure value, but
8788 we don't know what size it is. */
8789 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8791 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8793 rtx set = XVECEXP (operands[2], 0, i);
8794 emit_move_insn (SET_DEST (set), SET_SRC (set));
8797 /* The optimizer does not know that the call sets the function value
8798 registers we stored in the result block. We avoid problems by
8799 claiming that all hard registers are used and clobbered at this
8801 emit_insn (gen_blockage ());
8807 (define_expand "sibcall"
8808 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8813 (define_insn "*sibcall_symbolic_sp32"
8814 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8815 (match_operand 1 "" ""))
8818 "* return output_sibcall(insn, operands[0]);"
8819 [(set_attr "type" "sibcall")])
8821 (define_insn "*sibcall_symbolic_sp64"
8822 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8823 (match_operand 1 "" ""))
8826 "* return output_sibcall(insn, operands[0]);"
8827 [(set_attr "type" "sibcall")])
8829 (define_expand "sibcall_value"
8830 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8831 (call (match_operand 1 "" "") (const_int 0)))
8836 (define_insn "*sibcall_value_symbolic_sp32"
8837 [(set (match_operand 0 "" "=rf")
8838 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8839 (match_operand 2 "" "")))
8842 "* return output_sibcall(insn, operands[1]);"
8843 [(set_attr "type" "sibcall")])
8845 (define_insn "*sibcall_value_symbolic_sp64"
8846 [(set (match_operand 0 "" "")
8847 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8848 (match_operand 2 "" "")))
8851 "* return output_sibcall(insn, operands[1]);"
8852 [(set_attr "type" "sibcall")])
8854 (define_expand "sibcall_epilogue"
8859 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8860 ;; all of memory. This blocks insns from being moved across this point.
8862 (define_insn "blockage"
8863 [(unspec_volatile [(const_int 0)] 0)]
8866 [(set_attr "length" "0")])
8868 ;; Prepare to return any type including a structure value.
8870 (define_expand "untyped_return"
8871 [(match_operand:BLK 0 "memory_operand" "")
8872 (match_operand 1 "" "")]
8876 rtx valreg1 = gen_rtx_REG (DImode, 24);
8877 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8878 rtx result = operands[0];
8880 if (! TARGET_ARCH64)
8882 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8884 rtx value = gen_reg_rtx (SImode);
8886 /* Fetch the instruction where we will return to and see if it's an unimp
8887 instruction (the most significant 10 bits will be zero). If so,
8888 update the return address to skip the unimp instruction. */
8889 emit_move_insn (value,
8890 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8891 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8892 emit_insn (gen_update_return (rtnreg, value));
8895 /* Reload the function value registers. */
8896 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8897 emit_move_insn (valreg2,
8898 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8900 /* Put USE insns before the return. */
8901 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8902 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8904 /* Construct the return. */
8905 expand_null_return ();
8910 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8911 ;; and parts of the compiler don't want to believe that the add is needed.
8913 (define_insn "update_return"
8914 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8915 (match_operand:SI 1 "register_operand" "r")] 1)]
8917 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8918 [(set_attr "type" "multi")])
8920 (define_insn "return"
8924 "* return output_return (operands);"
8925 [(set_attr "type" "return")])
8928 [(set (match_operand:SI 0 "register_operand" "=r")
8929 (match_operand:SI 1 "arith_operand" "rI"))
8931 (use (reg:SI 31))])]
8932 "sparc_return_peephole_ok (operands[0], operands[1])"
8933 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8939 [(set_attr "type" "ialu")
8940 (set_attr "length" "1")])
8942 (define_expand "indirect_jump"
8943 [(set (pc) (match_operand 0 "address_operand" "p"))]
8947 (define_insn "*branch_sp32"
8948 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8951 [(set_attr "type" "uncond_branch")])
8953 (define_insn "*branch_sp64"
8954 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8957 [(set_attr "type" "uncond_branch")])
8959 ;; ??? Doesn't work with -mflat.
8960 (define_expand "nonlocal_goto"
8961 [(match_operand:SI 0 "general_operand" "")
8962 (match_operand:SI 1 "general_operand" "")
8963 (match_operand:SI 2 "general_operand" "")
8964 (match_operand:SI 3 "" "")]
8969 rtx chain = operands[0];
8971 rtx lab = operands[1];
8972 rtx stack = operands[2];
8973 rtx fp = operands[3];
8976 /* Trap instruction to flush all the register windows. */
8977 emit_insn (gen_flush_register_windows ());
8979 /* Load the fp value for the containing fn into %fp. This is needed
8980 because STACK refers to %fp. Note that virtual register instantiation
8981 fails if the virtual %fp isn't set from a register. */
8982 if (GET_CODE (fp) != REG)
8983 fp = force_reg (Pmode, fp);
8984 emit_move_insn (virtual_stack_vars_rtx, fp);
8986 /* Find the containing function's current nonlocal goto handler,
8987 which will do any cleanups and then jump to the label. */
8988 labreg = gen_rtx_REG (Pmode, 8);
8989 emit_move_insn (labreg, lab);
8991 /* Restore %fp from stack pointer value for containing function.
8992 The restore insn that follows will move this to %sp,
8993 and reload the appropriate value into %fp. */
8994 emit_move_insn (frame_pointer_rtx, stack);
8996 /* USE of frame_pointer_rtx added for consistency; not clear if
8998 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8999 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9002 /* Return, restoring reg window and jumping to goto handler. */
9003 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
9004 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
9006 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
9012 /* Put in the static chain register the nonlocal label address. */
9013 emit_move_insn (static_chain_rtx, chain);
9016 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
9017 emit_jump_insn (gen_goto_handler_and_restore (labreg));
9022 ;; Special trap insn to flush register windows.
9023 (define_insn "flush_register_windows"
9024 [(unspec_volatile [(const_int 0)] 1)]
9026 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
9027 [(set_attr "type" "misc")
9028 (set_attr "length" "1")])
9030 (define_insn "goto_handler_and_restore"
9031 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
9032 "GET_MODE (operands[0]) == Pmode"
9033 "jmp\\t%0+0\\n\\trestore"
9034 [(set_attr "type" "misc")
9035 (set_attr "length" "2")])
9037 ;;(define_insn "goto_handler_and_restore_v9"
9038 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
9039 ;; (match_operand:SI 1 "register_operand" "=r,r")
9040 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
9041 ;; "TARGET_V9 && ! TARGET_ARCH64"
9043 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
9044 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
9045 ;; [(set_attr "type" "misc")
9046 ;; (set_attr "length" "2,3")])
9048 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
9049 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
9050 ;; (match_operand:DI 1 "register_operand" "=r,r")
9051 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
9052 ;; "TARGET_V9 && TARGET_ARCH64"
9054 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
9055 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
9056 ;; [(set_attr "type" "misc")
9057 ;; (set_attr "length" "2,3")])
9059 ;; For __builtin_setjmp we need to flush register windows iff the function
9060 ;; calls alloca as well, because otherwise the register window might be
9061 ;; saved after %sp adjustement and thus setjmp would crash
9062 (define_expand "builtin_setjmp_setup"
9063 [(match_operand 0 "register_operand" "r")]
9067 emit_insn (gen_do_builtin_setjmp_setup ());
9071 (define_insn "do_builtin_setjmp_setup"
9072 [(unspec_volatile [(const_int 0)] 5)]
9076 if (!current_function_calls_alloca)
9082 [(set_attr "type" "misc")
9083 (set_attr "length" "1")])
9085 ;; Pattern for use after a setjmp to store FP and the return register
9086 ;; into the stack area.
9088 (define_expand "setjmp"
9094 emit_insn (gen_setjmp_64 ());
9096 emit_insn (gen_setjmp_32 ());
9100 (define_expand "setjmp_32"
9101 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
9102 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
9105 { operands[0] = frame_pointer_rtx; }")
9107 (define_expand "setjmp_64"
9108 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
9109 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
9112 { operands[0] = frame_pointer_rtx; }")
9114 ;; Special pattern for the FLUSH instruction.
9116 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
9117 ; of the define_insn otherwise missing a mode. We make "flush", aka
9118 ; gen_flush, the default one since sparc_initialize_trampoline uses
9119 ; it on SImode mem values.
9121 (define_insn "flush"
9122 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
9124 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
9125 [(set_attr "type" "misc")])
9127 (define_insn "flushdi"
9128 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
9130 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
9131 [(set_attr "type" "misc")])
9136 ;; The scan instruction searches from the most significant bit while ffs
9137 ;; searches from the least significant bit. The bit index and treatment of
9138 ;; zero also differ. It takes at least 7 instructions to get the proper
9139 ;; result. Here is an obvious 8 instruction sequence.
9142 (define_insn "ffssi2"
9143 [(set (match_operand:SI 0 "register_operand" "=&r")
9144 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
9145 (clobber (match_scratch:SI 2 "=&r"))]
9146 "TARGET_SPARCLITE || TARGET_SPARCLET"
9149 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\";
9151 [(set_attr "type" "multi")
9152 (set_attr "length" "8")])
9154 ;; ??? This should be a define expand, so that the extra instruction have
9155 ;; a chance of being optimized away.
9157 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
9158 ;; does, but no one uses that and we don't have a switch for it.
9160 ;(define_insn "ffsdi2"
9161 ; [(set (match_operand:DI 0 "register_operand" "=&r")
9162 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
9163 ; (clobber (match_scratch:DI 2 "=&r"))]
9165 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
9166 ; [(set_attr "type" "multi")
9167 ; (set_attr "length" "4")])
9171 ;; Peepholes go at the end.
9173 ;; Optimize consecutive loads or stores into ldd and std when possible.
9174 ;; The conditions in which we do this are very restricted and are
9175 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
9178 [(set (match_operand:SI 0 "memory_operand" "")
9180 (set (match_operand:SI 1 "memory_operand" "")
9183 && ! MEM_VOLATILE_P (operands[0])
9184 && ! MEM_VOLATILE_P (operands[1])
9185 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
9189 [(set (match_operand:SI 0 "memory_operand" "")
9191 (set (match_operand:SI 1 "memory_operand" "")
9194 && ! MEM_VOLATILE_P (operands[0])
9195 && ! MEM_VOLATILE_P (operands[1])
9196 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
9200 [(set (match_operand:SI 0 "register_operand" "=rf")
9201 (match_operand:SI 1 "memory_operand" ""))
9202 (set (match_operand:SI 2 "register_operand" "=rf")
9203 (match_operand:SI 3 "memory_operand" ""))]
9204 "registers_ok_for_ldd_peep (operands[0], operands[2])
9205 && ! MEM_VOLATILE_P (operands[1])
9206 && ! MEM_VOLATILE_P (operands[3])
9207 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9211 [(set (match_operand:SI 0 "memory_operand" "")
9212 (match_operand:SI 1 "register_operand" "rf"))
9213 (set (match_operand:SI 2 "memory_operand" "")
9214 (match_operand:SI 3 "register_operand" "rf"))]
9215 "registers_ok_for_ldd_peep (operands[1], operands[3])
9216 && ! MEM_VOLATILE_P (operands[0])
9217 && ! MEM_VOLATILE_P (operands[2])
9218 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9222 [(set (match_operand:SF 0 "register_operand" "=fr")
9223 (match_operand:SF 1 "memory_operand" ""))
9224 (set (match_operand:SF 2 "register_operand" "=fr")
9225 (match_operand:SF 3 "memory_operand" ""))]
9226 "registers_ok_for_ldd_peep (operands[0], operands[2])
9227 && ! MEM_VOLATILE_P (operands[1])
9228 && ! MEM_VOLATILE_P (operands[3])
9229 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9233 [(set (match_operand:SF 0 "memory_operand" "")
9234 (match_operand:SF 1 "register_operand" "fr"))
9235 (set (match_operand:SF 2 "memory_operand" "")
9236 (match_operand:SF 3 "register_operand" "fr"))]
9237 "registers_ok_for_ldd_peep (operands[1], operands[3])
9238 && ! MEM_VOLATILE_P (operands[0])
9239 && ! MEM_VOLATILE_P (operands[2])
9240 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9244 [(set (match_operand:SI 0 "register_operand" "=rf")
9245 (match_operand:SI 1 "memory_operand" ""))
9246 (set (match_operand:SI 2 "register_operand" "=rf")
9247 (match_operand:SI 3 "memory_operand" ""))]
9248 "registers_ok_for_ldd_peep (operands[2], operands[0])
9249 && ! MEM_VOLATILE_P (operands[3])
9250 && ! MEM_VOLATILE_P (operands[1])
9251 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9255 [(set (match_operand:SI 0 "memory_operand" "")
9256 (match_operand:SI 1 "register_operand" "rf"))
9257 (set (match_operand:SI 2 "memory_operand" "")
9258 (match_operand:SI 3 "register_operand" "rf"))]
9259 "registers_ok_for_ldd_peep (operands[3], operands[1])
9260 && ! MEM_VOLATILE_P (operands[2])
9261 && ! MEM_VOLATILE_P (operands[0])
9262 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9266 [(set (match_operand:SF 0 "register_operand" "=fr")
9267 (match_operand:SF 1 "memory_operand" ""))
9268 (set (match_operand:SF 2 "register_operand" "=fr")
9269 (match_operand:SF 3 "memory_operand" ""))]
9270 "registers_ok_for_ldd_peep (operands[2], operands[0])
9271 && ! MEM_VOLATILE_P (operands[3])
9272 && ! MEM_VOLATILE_P (operands[1])
9273 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9277 [(set (match_operand:SF 0 "memory_operand" "")
9278 (match_operand:SF 1 "register_operand" "fr"))
9279 (set (match_operand:SF 2 "memory_operand" "")
9280 (match_operand:SF 3 "register_operand" "fr"))]
9281 "registers_ok_for_ldd_peep (operands[3], operands[1])
9282 && ! MEM_VOLATILE_P (operands[2])
9283 && ! MEM_VOLATILE_P (operands[0])
9284 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9287 ;; Optimize the case of following a reg-reg move with a test
9288 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9289 ;; This can result from a float to fix conversion.
9292 [(set (match_operand:SI 0 "register_operand" "=r")
9293 (match_operand:SI 1 "register_operand" "r"))
9295 (compare:CC (match_operand:SI 2 "register_operand" "r")
9297 "(rtx_equal_p (operands[2], operands[0])
9298 || rtx_equal_p (operands[2], operands[1]))
9299 && ! FP_REG_P (operands[0])
9300 && ! FP_REG_P (operands[1])"
9304 [(set (match_operand:DI 0 "register_operand" "=r")
9305 (match_operand:DI 1 "register_operand" "r"))
9307 (compare:CCX (match_operand:DI 2 "register_operand" "r")
9310 && (rtx_equal_p (operands[2], operands[0])
9311 || rtx_equal_p (operands[2], operands[1]))
9312 && ! FP_REG_P (operands[0])
9313 && ! FP_REG_P (operands[1])"
9316 ;; Return peepholes. First the "normal" ones.
9317 ;; These are necessary to catch insns ending up in the epilogue delay list.
9319 (define_insn "*return_qi"
9320 [(set (match_operand:QI 0 "restore_operand" "")
9321 (match_operand:QI 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\\n\\trestore %%g0, %1, %Y0\";
9334 [(set_attr "type" "multi")])
9336 (define_insn "*return_hi"
9337 [(set (match_operand:HI 0 "restore_operand" "")
9338 (match_operand:HI 1 "arith_operand" "rI"))
9343 if (! TARGET_ARCH64 && current_function_returns_struct)
9344 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9345 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9346 || IN_OR_GLOBAL_P (operands[1])))
9347 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9349 return \"ret\;restore %%g0, %1, %Y0\";
9351 [(set_attr "type" "multi")])
9353 (define_insn "*return_si"
9354 [(set (match_operand:SI 0 "restore_operand" "")
9355 (match_operand:SI 1 "arith_operand" "rI"))
9360 if (! TARGET_ARCH64 && current_function_returns_struct)
9361 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9362 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9363 || 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 ;; The following pattern is only generated by delayed-branch scheduling,
9371 ;; when the insn winds up in the epilogue. This can happen not only when
9372 ;; ! TARGET_FPU because we move complex types around by parts using
9374 (define_insn "*return_sf_no_fpu"
9375 [(set (match_operand:SF 0 "restore_operand" "=r")
9376 (match_operand:SF 1 "register_operand" "r"))
9381 if (! TARGET_ARCH64 && current_function_returns_struct)
9382 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9383 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9384 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9386 return \"ret\;restore %%g0, %1, %Y0\";
9388 [(set_attr "type" "multi")])
9390 (define_insn "*return_df_no_fpu"
9391 [(set (match_operand:DF 0 "restore_operand" "=r")
9392 (match_operand:DF 1 "register_operand" "r"))
9394 "! TARGET_EPILOGUE && TARGET_ARCH64"
9397 if (IN_OR_GLOBAL_P (operands[1]))
9398 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9400 return \"ret\;restore %%g0, %1, %Y0\";
9402 [(set_attr "type" "multi")])
9404 (define_insn "*return_addsi"
9405 [(set (match_operand:SI 0 "restore_operand" "")
9406 (plus:SI (match_operand:SI 1 "register_operand" "r")
9407 (match_operand:SI 2 "arith_operand" "rI")))
9412 if (! TARGET_ARCH64 && current_function_returns_struct)
9413 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9414 /* If operands are global or in registers, can use return */
9415 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9416 && (GET_CODE (operands[2]) == CONST_INT
9417 || IN_OR_GLOBAL_P (operands[2])))
9418 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9420 return \"ret\;restore %r1, %2, %Y0\";
9422 [(set_attr "type" "multi")])
9424 (define_insn "*return_losum_si"
9425 [(set (match_operand:SI 0 "restore_operand" "")
9426 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9427 (match_operand:SI 2 "immediate_operand" "in")))
9429 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9432 if (! TARGET_ARCH64 && current_function_returns_struct)
9433 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9434 /* If operands are global or in registers, can use return */
9435 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9436 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9438 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9440 [(set_attr "type" "multi")])
9442 (define_insn "*return_di"
9443 [(set (match_operand:DI 0 "restore_operand" "")
9444 (match_operand:DI 1 "arith_double_operand" "rHI"))
9446 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9447 "ret\;restore %%g0, %1, %Y0"
9448 [(set_attr "type" "multi")])
9450 (define_insn "*return_adddi"
9451 [(set (match_operand:DI 0 "restore_operand" "")
9452 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9453 (match_operand:DI 2 "arith_double_operand" "rHI")))
9455 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9456 "ret\;restore %r1, %2, %Y0"
9457 [(set_attr "type" "multi")])
9459 (define_insn "*return_losum_di"
9460 [(set (match_operand:DI 0 "restore_operand" "")
9461 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9462 (match_operand:DI 2 "immediate_operand" "in")))
9464 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9465 "ret\;restore %r1, %%lo(%a2), %Y0"
9466 [(set_attr "type" "multi")])
9468 ;; The following pattern is only generated by delayed-branch scheduling,
9469 ;; when the insn winds up in the epilogue.
9470 (define_insn "*return_sf"
9472 (match_operand:SF 0 "register_operand" "f"))
9475 "ret\;fmovs\\t%0, %%f0"
9476 [(set_attr "type" "multi")])
9478 ;; Now peepholes to do a call followed by a jump.
9481 [(parallel [(set (match_operand 0 "" "")
9482 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9483 (match_operand 2 "" "")))
9484 (clobber (reg:SI 15))])
9485 (set (pc) (label_ref (match_operand 3 "" "")))]
9486 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9487 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9488 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9491 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9492 (match_operand 1 "" ""))
9493 (clobber (reg:SI 15))])
9494 (set (pc) (label_ref (match_operand 2 "" "")))]
9495 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9496 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9497 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9500 [(parallel [(set (match_operand 0 "" "")
9501 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9502 (match_operand 2 "" "")))
9503 (clobber (reg:DI 15))])
9504 (set (pc) (label_ref (match_operand 3 "" "")))]
9506 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9507 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9508 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9511 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9512 (match_operand 1 "" ""))
9513 (clobber (reg:DI 15))])
9514 (set (pc) (label_ref (match_operand 2 "" "")))]
9516 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9517 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9518 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9520 (define_expand "prologue"
9522 "flag_pic && current_function_uses_pic_offset_table"
9525 load_pic_register ();
9529 ;; We need to reload %l7 for -mflat -fpic,
9530 ;; otherwise %l7 should be preserved simply
9531 ;; by loading the function's register window
9532 (define_expand "exception_receiver"
9534 "TARGET_FLAT && flag_pic"
9537 load_pic_register ();
9542 (define_expand "builtin_setjmp_receiver"
9543 [(label_ref (match_operand 0 "" ""))]
9544 "TARGET_FLAT && flag_pic"
9547 load_pic_register ();
9552 [(trap_if (const_int 1) (const_int 5))]
9555 [(set_attr "type" "misc")
9556 (set_attr "length" "1")])
9558 (define_expand "conditional_trap"
9559 [(trap_if (match_operator 0 "noov_compare_op"
9560 [(match_dup 2) (match_dup 3)])
9561 (match_operand:SI 1 "arith_operand" ""))]
9563 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9564 sparc_compare_op0, sparc_compare_op1);
9565 operands[3] = const0_rtx;")
9568 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9569 (match_operand:SI 1 "arith_operand" "rM"))]
9572 [(set_attr "type" "misc")
9573 (set_attr "length" "1")])
9576 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9577 (match_operand:SI 1 "arith_operand" "rM"))]
9580 [(set_attr "type" "misc")
9581 (set_attr "length" "1")])