1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987-2014 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
4 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25 (define_c_enum "unspec" [
97 (define_c_enum "unspecv" [
99 UNSPECV_PROBE_STACK_RANGE
204 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
205 (define_mode_iterator I [QI HI SI DI])
206 (define_mode_iterator F [SF DF TF])
208 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
209 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
210 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
211 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
212 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
214 ;; Attribute for cpu type.
215 ;; These must match the values of the enum processor_type in sparc-opts.h.
237 (const (symbol_ref "sparc_cpu_attr")))
239 ;; Attribute for the instruction set.
240 ;; At present we only need to distinguish v9/!v9, but for clarity we
241 ;; test TARGET_V8 too.
242 (define_attr "isa" "v7,v8,v9,sparclet"
244 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
245 (symbol_ref "TARGET_V8") (const_string "v8")
246 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
247 (const_string "v7"))))
249 (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3" (const_string "none"))
251 (define_attr "enabled" ""
252 (cond [(eq_attr "cpu_feature" "none") (const_int 1)
253 (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU")
254 (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && ! TARGET_V9")
255 (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9")
256 (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS")
257 (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")]
264 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
265 cbcond,uncond_cbcond,
273 fga,visl,vismv,fgm_pack,fgm_mul,pdist,pdistn,edge,edgen,gsr,array,
276 multi,savew,flushw,iflush,trap"
277 (const_string "ialu"))
279 ;; True if branch/call has empty delay slot and will emit a nop in it
280 (define_attr "empty_delay_slot" "false,true"
281 (symbol_ref "(empty_delay_slot (insn)
282 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
284 ;; True if we are making use of compare-and-branch instructions.
285 ;; True if we should emit a nop after a cbcond instruction
286 (define_attr "emit_cbcond_nop" "false,true"
287 (symbol_ref "(emit_cbcond_nop (insn)
288 ? EMIT_CBCOND_NOP_TRUE : EMIT_CBCOND_NOP_FALSE)"))
290 (define_attr "branch_type" "none,icc,fcc,reg"
291 (const_string "none"))
293 (define_attr "pic" "false,true"
294 (symbol_ref "(flag_pic != 0
295 ? PIC_TRUE : PIC_FALSE)"))
297 (define_attr "calls_alloca" "false,true"
298 (symbol_ref "(cfun->calls_alloca != 0
299 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
301 (define_attr "calls_eh_return" "false,true"
302 (symbol_ref "(crtl->calls_eh_return != 0
303 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
305 (define_attr "leaf_function" "false,true"
306 (symbol_ref "(crtl->uses_only_leaf_regs != 0
307 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
309 (define_attr "delayed_branch" "false,true"
310 (symbol_ref "(flag_delayed_branch != 0
311 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
313 (define_attr "flat" "false,true"
314 (symbol_ref "(TARGET_FLAT != 0
315 ? FLAT_TRUE : FLAT_FALSE)"))
317 (define_attr "fix_ut699" "false,true"
318 (symbol_ref "(sparc_fix_ut699 != 0
319 ? FIX_UT699_TRUE : FIX_UT699_FALSE)"))
321 ;; Length (in # of insns).
322 ;; Beware that setting a length greater or equal to 3 for conditional branches
323 ;; has a side-effect (see output_cbranch and output_v9branch).
324 (define_attr "length" ""
325 (cond [(eq_attr "type" "uncond_branch,call")
326 (if_then_else (eq_attr "empty_delay_slot" "true")
329 (eq_attr "type" "sibcall")
330 (if_then_else (eq_attr "leaf_function" "true")
331 (if_then_else (eq_attr "empty_delay_slot" "true")
334 (if_then_else (eq_attr "empty_delay_slot" "true")
337 (eq_attr "branch_type" "icc")
338 (if_then_else (match_operand 0 "noov_compare64_operator" "")
339 (if_then_else (lt (pc) (match_dup 1))
340 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
341 (if_then_else (eq_attr "empty_delay_slot" "true")
344 (if_then_else (eq_attr "empty_delay_slot" "true")
347 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
348 (if_then_else (eq_attr "empty_delay_slot" "true")
351 (if_then_else (eq_attr "empty_delay_slot" "true")
354 (if_then_else (eq_attr "empty_delay_slot" "true")
357 (eq_attr "branch_type" "fcc")
358 (if_then_else (match_operand 0 "fcc0_register_operand" "")
359 (if_then_else (eq_attr "empty_delay_slot" "true")
360 (if_then_else (not (match_test "TARGET_V9"))
363 (if_then_else (not (match_test "TARGET_V9"))
366 (if_then_else (lt (pc) (match_dup 2))
367 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
368 (if_then_else (eq_attr "empty_delay_slot" "true")
371 (if_then_else (eq_attr "empty_delay_slot" "true")
374 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
375 (if_then_else (eq_attr "empty_delay_slot" "true")
378 (if_then_else (eq_attr "empty_delay_slot" "true")
381 (eq_attr "branch_type" "reg")
382 (if_then_else (lt (pc) (match_dup 2))
383 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
384 (if_then_else (eq_attr "empty_delay_slot" "true")
387 (if_then_else (eq_attr "empty_delay_slot" "true")
390 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
391 (if_then_else (eq_attr "empty_delay_slot" "true")
394 (if_then_else (eq_attr "empty_delay_slot" "true")
397 (eq_attr "type" "cbcond")
398 (if_then_else (lt (pc) (match_dup 3))
399 (if_then_else (lt (minus (match_dup 3) (pc)) (const_int 500))
400 (if_then_else (eq_attr "emit_cbcond_nop" "true")
404 (if_then_else (lt (minus (pc) (match_dup 3)) (const_int 500))
405 (if_then_else (eq_attr "emit_cbcond_nop" "true")
409 (eq_attr "type" "uncond_cbcond")
410 (if_then_else (lt (pc) (match_dup 0))
411 (if_then_else (lt (minus (match_dup 0) (pc)) (const_int 500))
412 (if_then_else (eq_attr "emit_cbcond_nop" "true")
416 (if_then_else (lt (minus (pc) (match_dup 0)) (const_int 500))
417 (if_then_else (eq_attr "emit_cbcond_nop" "true")
424 (define_attr "fptype" "single,double"
425 (const_string "single"))
427 ;; FP precision specific to the UT699.
428 (define_attr "fptype_ut699" "none,single"
429 (const_string "none"))
431 ;; UltraSPARC-III integer load type.
432 (define_attr "us3load_type" "2cycle,3cycle"
433 (const_string "2cycle"))
435 (define_asm_attributes
436 [(set_attr "length" "2")
437 (set_attr "type" "multi")])
439 ;; Attributes for branch scheduling
440 (define_attr "in_call_delay" "false,true"
441 (symbol_ref "(eligible_for_call_delay (insn)
442 ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)"))
444 (define_attr "in_sibcall_delay" "false,true"
445 (symbol_ref "(eligible_for_sibcall_delay (insn)
446 ? IN_SIBCALL_DELAY_TRUE : IN_SIBCALL_DELAY_FALSE)"))
448 (define_attr "in_return_delay" "false,true"
449 (symbol_ref "(eligible_for_return_delay (insn)
450 ? IN_RETURN_DELAY_TRUE : IN_RETURN_DELAY_FALSE)"))
452 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
453 ;; branches. This would allow us to remove the nop always inserted before
454 ;; a floating point branch.
456 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
457 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
458 ;; This is because doing so will add several pipeline stalls to the path
459 ;; that the load/store did not come from. Unfortunately, there is no way
460 ;; to prevent fill_eager_delay_slots from using load/store without completely
461 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
462 ;; because it prevents us from moving back the final store of inner loops.
464 (define_attr "in_branch_delay" "false,true"
465 (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
466 (const_string "false")
467 (and (eq_attr "fix_ut699" "true") (eq_attr "type" "load,sload"))
468 (const_string "false")
469 (and (eq_attr "fix_ut699" "true")
470 (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts")
471 (ior (eq_attr "fptype" "single")
472 (eq_attr "fptype_ut699" "single"))))
473 (const_string "false")
474 (eq_attr "length" "1")
475 (const_string "true")
476 ] (const_string "false")))
478 (define_delay (eq_attr "type" "call")
479 [(eq_attr "in_call_delay" "true") (nil) (nil)])
481 (define_delay (eq_attr "type" "sibcall")
482 [(eq_attr "in_sibcall_delay" "true") (nil) (nil)])
484 (define_delay (eq_attr "type" "return")
485 [(eq_attr "in_return_delay" "true") (nil) (nil)])
487 (define_delay (eq_attr "type" "branch")
488 [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")])
490 (define_delay (eq_attr "type" "uncond_branch")
491 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
494 ;; Include SPARC DFA schedulers
496 (include "cypress.md")
497 (include "supersparc.md")
498 (include "hypersparc.md")
500 (include "sparclet.md")
501 (include "ultra1_2.md")
502 (include "ultra3.md")
503 (include "niagara.md")
504 (include "niagara2.md")
505 (include "niagara4.md")
508 ;; Operand and operator predicates and constraints
510 (include "predicates.md")
511 (include "constraints.md")
514 ;; Compare instructions.
516 ;; These are just the DEFINE_INSNs to match the patterns and the
517 ;; DEFINE_SPLITs for some of the scc insns that actually require
518 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
520 ;; The compare DEFINE_INSNs.
522 (define_insn "*cmpsi_insn"
523 [(set (reg:CC CC_REG)
524 (compare:CC (match_operand:SI 0 "register_operand" "r")
525 (match_operand:SI 1 "arith_operand" "rI")))]
528 [(set_attr "type" "compare")])
530 (define_insn "*cmpdi_sp64"
531 [(set (reg:CCX CC_REG)
532 (compare:CCX (match_operand:DI 0 "register_operand" "r")
533 (match_operand:DI 1 "arith_operand" "rI")))]
536 [(set_attr "type" "compare")])
538 (define_insn "*cmpsf_fpe"
539 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
540 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
541 (match_operand:SF 2 "register_operand" "f")))]
545 return "fcmpes\t%0, %1, %2";
546 return "fcmpes\t%1, %2";
548 [(set_attr "type" "fpcmp")])
550 (define_insn "*cmpdf_fpe"
551 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
552 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
553 (match_operand:DF 2 "register_operand" "e")))]
557 return "fcmped\t%0, %1, %2";
558 return "fcmped\t%1, %2";
560 [(set_attr "type" "fpcmp")
561 (set_attr "fptype" "double")])
563 (define_insn "*cmptf_fpe"
564 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
565 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
566 (match_operand:TF 2 "register_operand" "e")))]
567 "TARGET_FPU && TARGET_HARD_QUAD"
570 return "fcmpeq\t%0, %1, %2";
571 return "fcmpeq\t%1, %2";
573 [(set_attr "type" "fpcmp")])
575 (define_insn "*cmpsf_fp"
576 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
577 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
578 (match_operand:SF 2 "register_operand" "f")))]
582 return "fcmps\t%0, %1, %2";
583 return "fcmps\t%1, %2";
585 [(set_attr "type" "fpcmp")])
587 (define_insn "*cmpdf_fp"
588 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
589 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
590 (match_operand:DF 2 "register_operand" "e")))]
594 return "fcmpd\t%0, %1, %2";
595 return "fcmpd\t%1, %2";
597 [(set_attr "type" "fpcmp")
598 (set_attr "fptype" "double")])
600 (define_insn "*cmptf_fp"
601 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
602 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
603 (match_operand:TF 2 "register_operand" "e")))]
604 "TARGET_FPU && TARGET_HARD_QUAD"
607 return "fcmpq\t%0, %1, %2";
608 return "fcmpq\t%1, %2";
610 [(set_attr "type" "fpcmp")])
612 ;; Next come the scc insns.
614 ;; Note that the boolean result (operand 0) takes on DImode
615 ;; (not SImode) when TARGET_ARCH64.
617 (define_expand "cstoresi4"
618 [(use (match_operator 1 "comparison_operator"
619 [(match_operand:SI 2 "compare_operand" "")
620 (match_operand:SI 3 "arith_operand" "")]))
621 (clobber (match_operand:SI 0 "cstore_result_operand"))]
624 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
625 operands[2] = force_reg (SImode, operands[2]);
626 if (emit_scc_insn (operands)) DONE; else FAIL;
629 (define_expand "cstoredi4"
630 [(use (match_operator 1 "comparison_operator"
631 [(match_operand:DI 2 "compare_operand" "")
632 (match_operand:DI 3 "arith_operand" "")]))
633 (clobber (match_operand:SI 0 "cstore_result_operand"))]
636 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
637 operands[2] = force_reg (DImode, operands[2]);
638 if (emit_scc_insn (operands)) DONE; else FAIL;
641 (define_expand "cstore<F:mode>4"
642 [(use (match_operator 1 "comparison_operator"
643 [(match_operand:F 2 "register_operand" "")
644 (match_operand:F 3 "register_operand" "")]))
645 (clobber (match_operand:SI 0 "cstore_result_operand"))]
647 { if (emit_scc_insn (operands)) DONE; else FAIL; })
651 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
652 ;; generate addcc/subcc instructions.
654 (define_expand "seqsi<P:mode>_special"
656 (xor:SI (match_operand:SI 1 "register_operand" "")
657 (match_operand:SI 2 "register_operand" "")))
658 (parallel [(set (match_operand:P 0 "register_operand" "")
659 (eq:P (match_dup 3) (const_int 0)))
660 (clobber (reg:CC CC_REG))])]
662 { operands[3] = gen_reg_rtx (SImode); })
664 (define_expand "seqdi_special"
666 (xor:DI (match_operand:DI 1 "register_operand" "")
667 (match_operand:DI 2 "register_operand" "")))
668 (set (match_operand:DI 0 "register_operand" "")
669 (eq:DI (match_dup 3) (const_int 0)))]
671 { operands[3] = gen_reg_rtx (DImode); })
673 (define_expand "snesi<P:mode>_special"
675 (xor:SI (match_operand:SI 1 "register_operand" "")
676 (match_operand:SI 2 "register_operand" "")))
677 (parallel [(set (match_operand:P 0 "register_operand" "")
678 (ne:P (match_dup 3) (const_int 0)))
679 (clobber (reg:CC CC_REG))])]
681 { operands[3] = gen_reg_rtx (SImode); })
683 (define_expand "snedi_special"
685 (xor:DI (match_operand:DI 1 "register_operand" "")
686 (match_operand:DI 2 "register_operand" "")))
687 (set (match_operand:DI 0 "register_operand" "")
688 (ne:DI (match_dup 3) (const_int 0)))]
689 "TARGET_ARCH64 && ! TARGET_VIS3"
690 { operands[3] = gen_reg_rtx (DImode); })
692 (define_expand "snedi_special_vis3"
694 (xor:DI (match_operand:DI 1 "register_operand" "")
695 (match_operand:DI 2 "register_operand" "")))
696 (parallel [(set (match_operand:DI 0 "register_operand" "")
697 (ne:DI (match_dup 3) (const_int 0)))
698 (clobber (reg:CCX CC_REG))])]
699 "TARGET_ARCH64 && TARGET_VIS3"
700 { operands[3] = gen_reg_rtx (DImode); })
703 ;; Now the DEFINE_INSNs for the scc cases.
705 ;; The SEQ and SNE patterns are special because they can be done
706 ;; without any branching and do not involve a COMPARE. We want
707 ;; them to always use the splits below so the results can be
710 (define_insn_and_split "*snesi<P:mode>_zero"
711 [(set (match_operand:P 0 "register_operand" "=r")
712 (ne:P (match_operand:SI 1 "register_operand" "r")
714 (clobber (reg:CC CC_REG))]
718 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
720 (set (match_dup 0) (ltu:P (reg:CC CC_REG) (const_int 0)))]
722 [(set_attr "length" "2")])
724 (define_insn_and_split "*neg_snesisi_zero"
725 [(set (match_operand:SI 0 "register_operand" "=r")
726 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
728 (clobber (reg:CC CC_REG))]
732 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
734 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
736 [(set_attr "length" "2")])
738 (define_insn_and_split "*neg_snesidi_zero"
739 [(set (match_operand:DI 0 "register_operand" "=r")
740 (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r")
742 (clobber (reg:CC CC_REG))]
746 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
748 (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG)
751 [(set_attr "length" "2")])
753 (define_insn_and_split "*snedi_zero"
754 [(set (match_operand:DI 0 "register_operand" "=&r")
755 (ne:DI (match_operand:DI 1 "register_operand" "r")
757 "TARGET_ARCH64 && ! TARGET_VIS3"
759 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
760 [(set (match_dup 0) (const_int 0))
761 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
766 [(set_attr "length" "2")])
768 (define_insn_and_split "*snedi_zero_vis3"
769 [(set (match_operand:DI 0 "register_operand" "=r")
770 (ne:DI (match_operand:DI 1 "register_operand" "r")
772 (clobber (reg:CCX CC_REG))]
773 "TARGET_ARCH64 && TARGET_VIS3"
776 [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
778 (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
780 [(set_attr "length" "2")])
782 (define_insn_and_split "*neg_snedi_zero"
783 [(set (match_operand:DI 0 "register_operand" "=&r")
784 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
788 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
789 [(set (match_dup 0) (const_int 0))
790 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
795 [(set_attr "length" "2")])
797 (define_insn_and_split "*snedi_zero_trunc"
798 [(set (match_operand:SI 0 "register_operand" "=&r")
799 (ne:SI (match_operand:DI 1 "register_operand" "r")
801 "TARGET_ARCH64 && ! TARGET_VIS3"
803 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
804 [(set (match_dup 0) (const_int 0))
805 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
810 [(set_attr "length" "2")])
812 (define_insn_and_split "*snedi_zero_trunc_vis3"
813 [(set (match_operand:SI 0 "register_operand" "=r")
814 (ne:SI (match_operand:DI 1 "register_operand" "r")
816 (clobber (reg:CCX CC_REG))]
817 "TARGET_ARCH64 && TARGET_VIS3"
820 [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
822 (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
824 [(set_attr "length" "2")])
826 (define_insn_and_split "*seqsi<P:mode>_zero"
827 [(set (match_operand:P 0 "register_operand" "=r")
828 (eq:P (match_operand:SI 1 "register_operand" "r")
830 (clobber (reg:CC CC_REG))]
834 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
836 (set (match_dup 0) (geu:P (reg:CC CC_REG) (const_int 0)))]
838 [(set_attr "length" "2")])
840 (define_insn_and_split "*neg_seqsisi_zero"
841 [(set (match_operand:SI 0 "register_operand" "=r")
842 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
844 (clobber (reg:CC CC_REG))]
848 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
850 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
852 [(set_attr "length" "2")])
854 (define_insn_and_split "*neg_seqsidi_zero"
855 [(set (match_operand:DI 0 "register_operand" "=r")
856 (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r")
858 (clobber (reg:CC CC_REG))]
862 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
864 (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG)
867 [(set_attr "length" "2")])
869 (define_insn_and_split "*seqdi_zero"
870 [(set (match_operand:DI 0 "register_operand" "=&r")
871 (eq:DI (match_operand:DI 1 "register_operand" "r")
875 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
876 [(set (match_dup 0) (const_int 0))
877 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
882 [(set_attr "length" "2")])
884 (define_insn_and_split "*neg_seqdi_zero"
885 [(set (match_operand:DI 0 "register_operand" "=&r")
886 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
890 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
891 [(set (match_dup 0) (const_int 0))
892 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
897 [(set_attr "length" "2")])
899 (define_insn_and_split "*seqdi_zero_trunc"
900 [(set (match_operand:SI 0 "register_operand" "=&r")
901 (eq:SI (match_operand:DI 1 "register_operand" "r")
905 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
906 [(set (match_dup 0) (const_int 0))
907 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
912 [(set_attr "length" "2")])
914 ;; We can also do (x + (i == 0)) and related, so put them in.
915 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
918 (define_insn_and_split "*x_plus_i_ne_0"
919 [(set (match_operand:SI 0 "register_operand" "=r")
920 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
922 (match_operand:SI 2 "register_operand" "r")))
923 (clobber (reg:CC CC_REG))]
927 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
929 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
932 [(set_attr "length" "2")])
934 (define_insn_and_split "*x_minus_i_ne_0"
935 [(set (match_operand:SI 0 "register_operand" "=r")
936 (minus:SI (match_operand:SI 2 "register_operand" "r")
937 (ne:SI (match_operand:SI 1 "register_operand" "r")
939 (clobber (reg:CC CC_REG))]
943 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
945 (set (match_dup 0) (minus:SI (match_dup 2)
946 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
948 [(set_attr "length" "2")])
950 (define_insn_and_split "*x_plus_i_eq_0"
951 [(set (match_operand:SI 0 "register_operand" "=r")
952 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
954 (match_operand:SI 2 "register_operand" "r")))
955 (clobber (reg:CC CC_REG))]
959 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
961 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
964 [(set_attr "length" "2")])
966 (define_insn_and_split "*x_minus_i_eq_0"
967 [(set (match_operand:SI 0 "register_operand" "=r")
968 (minus:SI (match_operand:SI 2 "register_operand" "r")
969 (eq:SI (match_operand:SI 1 "register_operand" "r")
971 (clobber (reg:CC CC_REG))]
975 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
977 (set (match_dup 0) (minus:SI (match_dup 2)
978 (geu:SI (reg:CC CC_REG) (const_int 0))))]
980 [(set_attr "length" "2")])
982 ;; We can also do GEU and LTU directly, but these operate after a compare.
983 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
986 (define_insn "*sltu<P:mode>_insn"
987 [(set (match_operand:P 0 "register_operand" "=r")
988 (ltu:P (reg:CC CC_REG) (const_int 0)))]
991 [(set_attr "type" "ialuX")])
993 (define_insn "*sltu_insn_vis3"
994 [(set (match_operand:DI 0 "register_operand" "=r")
995 (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
996 "TARGET_ARCH64 && TARGET_VIS3"
997 "addxc\t%%g0, %%g0, %0"
998 [(set_attr "type" "ialuX")])
1000 (define_insn "*sltu_insn_vis3_trunc"
1001 [(set (match_operand:SI 0 "register_operand" "=r")
1002 (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
1003 "TARGET_ARCH64 && TARGET_VIS3"
1004 "addxc\t%%g0, %%g0, %0"
1005 [(set_attr "type" "ialuX")])
1007 (define_insn "*neg_sltusi_insn"
1008 [(set (match_operand:SI 0 "register_operand" "=r")
1009 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1012 [(set_attr "type" "ialuX")])
1014 (define_insn "*neg_sltudi_insn"
1015 [(set (match_operand:DI 0 "register_operand" "=r")
1016 (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))]
1019 [(set_attr "type" "ialuX")])
1021 (define_insn "*neg_sltu_minus_x"
1022 [(set (match_operand:SI 0 "register_operand" "=r")
1023 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
1024 (match_operand:SI 1 "arith_operand" "rI")))]
1026 "subx\t%%g0, %1, %0"
1027 [(set_attr "type" "ialuX")])
1029 (define_insn "*neg_sltu_plus_x"
1030 [(set (match_operand:SI 0 "register_operand" "=r")
1031 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1032 (match_operand:SI 1 "arith_operand" "rI"))))]
1034 "subx\t%%g0, %1, %0"
1035 [(set_attr "type" "ialuX")])
1037 (define_insn "*sgeu<P:mode>_insn"
1038 [(set (match_operand:P 0 "register_operand" "=r")
1039 (geu:P (reg:CC CC_REG) (const_int 0)))]
1041 "subx\t%%g0, -1, %0"
1042 [(set_attr "type" "ialuX")])
1044 (define_insn "*neg_sgeusi_insn"
1045 [(set (match_operand:SI 0 "register_operand" "=r")
1046 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
1048 "addx\t%%g0, -1, %0"
1049 [(set_attr "type" "ialuX")])
1051 (define_insn "*neg_sgeudi_insn"
1052 [(set (match_operand:DI 0 "register_operand" "=r")
1053 (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))]
1055 "addx\t%%g0, -1, %0"
1056 [(set_attr "type" "ialuX")])
1058 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1059 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1062 (define_insn "*sltu_plus_x"
1063 [(set (match_operand:SI 0 "register_operand" "=r")
1064 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1065 (match_operand:SI 1 "arith_operand" "rI")))]
1067 "addx\t%%g0, %1, %0"
1068 [(set_attr "type" "ialuX")])
1070 (define_insn "*sltu_plus_x_plus_y"
1071 [(set (match_operand:SI 0 "register_operand" "=r")
1072 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1073 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1074 (match_operand:SI 2 "arith_operand" "rI"))))]
1077 [(set_attr "type" "ialuX")])
1079 (define_insn "*x_minus_sltu"
1080 [(set (match_operand:SI 0 "register_operand" "=r")
1081 (minus:SI (match_operand:SI 1 "register_operand" "r")
1082 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1085 [(set_attr "type" "ialuX")])
1087 ;; ??? Combine should canonicalize these next two to the same pattern.
1088 (define_insn "*x_minus_y_minus_sltu"
1089 [(set (match_operand:SI 0 "register_operand" "=r")
1090 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1091 (match_operand:SI 2 "arith_operand" "rI"))
1092 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1095 [(set_attr "type" "ialuX")])
1097 (define_insn "*x_minus_sltu_plus_y"
1098 [(set (match_operand:SI 0 "register_operand" "=r")
1099 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1100 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1101 (match_operand:SI 2 "arith_operand" "rI"))))]
1104 [(set_attr "type" "ialuX")])
1106 (define_insn "*sgeu_plus_x"
1107 [(set (match_operand:SI 0 "register_operand" "=r")
1108 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1109 (match_operand:SI 1 "register_operand" "r")))]
1112 [(set_attr "type" "ialuX")])
1114 (define_insn "*x_minus_sgeu"
1115 [(set (match_operand:SI 0 "register_operand" "=r")
1116 (minus:SI (match_operand:SI 1 "register_operand" "r")
1117 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1120 [(set_attr "type" "ialuX")])
1123 [(set (match_operand:SI 0 "register_operand" "")
1124 (match_operator:SI 2 "noov_compare_operator"
1125 [(match_operand 1 "icc_or_fcc_register_operand" "")
1128 && REGNO (operands[1]) == SPARC_ICC_REG
1129 && (GET_MODE (operands[1]) == CCXmode
1130 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1131 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1132 [(set (match_dup 0) (const_int 0))
1134 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1140 ;; These control RTL generation for conditional jump insns
1142 (define_expand "cbranchcc4"
1144 (if_then_else (match_operator 0 "comparison_operator"
1145 [(match_operand 1 "compare_operand" "")
1146 (match_operand 2 "const_zero_operand" "")])
1147 (label_ref (match_operand 3 "" ""))
1152 (define_expand "cbranchsi4"
1153 [(use (match_operator 0 "comparison_operator"
1154 [(match_operand:SI 1 "compare_operand" "")
1155 (match_operand:SI 2 "arith_operand" "")]))
1156 (use (match_operand 3 ""))]
1159 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1160 operands[1] = force_reg (SImode, operands[1]);
1161 emit_conditional_branch_insn (operands);
1165 (define_expand "cbranchdi4"
1166 [(use (match_operator 0 "comparison_operator"
1167 [(match_operand:DI 1 "compare_operand" "")
1168 (match_operand:DI 2 "arith_operand" "")]))
1169 (use (match_operand 3 ""))]
1172 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1173 operands[1] = force_reg (DImode, operands[1]);
1174 emit_conditional_branch_insn (operands);
1178 (define_expand "cbranch<F:mode>4"
1179 [(use (match_operator 0 "comparison_operator"
1180 [(match_operand:F 1 "register_operand" "")
1181 (match_operand:F 2 "register_operand" "")]))
1182 (use (match_operand 3 ""))]
1184 { emit_conditional_branch_insn (operands); DONE; })
1187 ;; Now match both normal and inverted jump.
1189 ;; XXX fpcmp nop braindamage
1190 (define_insn "*normal_branch"
1192 (if_then_else (match_operator 0 "noov_compare_operator"
1193 [(reg CC_REG) (const_int 0)])
1194 (label_ref (match_operand 1 "" ""))
1198 return output_cbranch (operands[0], operands[1], 1, 0,
1199 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1202 [(set_attr "type" "branch")
1203 (set_attr "branch_type" "icc")])
1205 ;; XXX fpcmp nop braindamage
1206 (define_insn "*inverted_branch"
1208 (if_then_else (match_operator 0 "noov_compare_operator"
1209 [(reg CC_REG) (const_int 0)])
1211 (label_ref (match_operand 1 "" ""))))]
1214 return output_cbranch (operands[0], operands[1], 1, 1,
1215 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1218 [(set_attr "type" "branch")
1219 (set_attr "branch_type" "icc")])
1221 ;; XXX fpcmp nop braindamage
1222 (define_insn "*normal_fp_branch"
1224 (if_then_else (match_operator 1 "comparison_operator"
1225 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1227 (label_ref (match_operand 2 "" ""))
1231 return output_cbranch (operands[1], operands[2], 2, 0,
1232 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1235 [(set_attr "type" "branch")
1236 (set_attr "branch_type" "fcc")])
1238 ;; XXX fpcmp nop braindamage
1239 (define_insn "*inverted_fp_branch"
1241 (if_then_else (match_operator 1 "comparison_operator"
1242 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1245 (label_ref (match_operand 2 "" ""))))]
1248 return output_cbranch (operands[1], operands[2], 2, 1,
1249 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1252 [(set_attr "type" "branch")
1253 (set_attr "branch_type" "fcc")])
1255 ;; XXX fpcmp nop braindamage
1256 (define_insn "*normal_fpe_branch"
1258 (if_then_else (match_operator 1 "comparison_operator"
1259 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1261 (label_ref (match_operand 2 "" ""))
1265 return output_cbranch (operands[1], operands[2], 2, 0,
1266 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1269 [(set_attr "type" "branch")
1270 (set_attr "branch_type" "fcc")])
1272 ;; XXX fpcmp nop braindamage
1273 (define_insn "*inverted_fpe_branch"
1275 (if_then_else (match_operator 1 "comparison_operator"
1276 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1279 (label_ref (match_operand 2 "" ""))))]
1282 return output_cbranch (operands[1], operands[2], 2, 1,
1283 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1286 [(set_attr "type" "branch")
1287 (set_attr "branch_type" "fcc")])
1289 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1290 ;; in the architecture.
1292 (define_insn "*cbcond_sp32"
1294 (if_then_else (match_operator 0 "noov_compare_operator"
1295 [(match_operand:SI 1 "register_operand" "r")
1296 (match_operand:SI 2 "arith5_operand" "rA")])
1297 (label_ref (match_operand 3 "" ""))
1301 return output_cbcond (operands[0], operands[3], insn);
1303 [(set_attr "type" "cbcond")])
1305 (define_insn "*cbcond_sp64"
1307 (if_then_else (match_operator 0 "noov_compare_operator"
1308 [(match_operand:DI 1 "register_operand" "r")
1309 (match_operand:DI 2 "arith5_operand" "rA")])
1310 (label_ref (match_operand 3 "" ""))
1312 "TARGET_ARCH64 && TARGET_CBCOND"
1314 return output_cbcond (operands[0], operands[3], insn);
1316 [(set_attr "type" "cbcond")])
1318 ;; There are no 32 bit brreg insns.
1321 (define_insn "*normal_int_branch_sp64"
1323 (if_then_else (match_operator 0 "v9_register_compare_operator"
1324 [(match_operand:DI 1 "register_operand" "r")
1326 (label_ref (match_operand 2 "" ""))
1330 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1331 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1334 [(set_attr "type" "branch")
1335 (set_attr "branch_type" "reg")])
1338 (define_insn "*inverted_int_branch_sp64"
1340 (if_then_else (match_operator 0 "v9_register_compare_operator"
1341 [(match_operand:DI 1 "register_operand" "r")
1344 (label_ref (match_operand 2 "" ""))))]
1347 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1348 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1351 [(set_attr "type" "branch")
1352 (set_attr "branch_type" "reg")])
1355 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1356 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1357 ;; that adds the PC value at the call point to register #(operand 3).
1359 ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..."
1360 ;; because the RDPC instruction is extremely expensive and incurs a complete
1361 ;; instruction pipeline flush.
1363 (define_insn "load_pcrel_sym<P:mode>"
1364 [(set (match_operand:P 0 "register_operand" "=r")
1365 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1366 (match_operand:P 2 "call_address_operand" "")
1367 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1368 (clobber (reg:P O7_REG))]
1369 "REGNO (operands[0]) == INTVAL (operands[3])"
1371 if (flag_delayed_branch)
1372 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1374 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1376 [(set (attr "type") (const_string "multi"))
1377 (set (attr "length")
1378 (if_then_else (eq_attr "delayed_branch" "true")
1383 ;; Integer move instructions
1385 (define_expand "movqi"
1386 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1387 (match_operand:QI 1 "general_operand" ""))]
1390 if (sparc_expand_move (QImode, operands))
1394 (define_insn "*movqi_insn"
1395 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1396 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1397 "(register_operand (operands[0], QImode)
1398 || register_or_zero_operand (operands[1], QImode))"
1403 [(set_attr "type" "*,load,store")
1404 (set_attr "us3load_type" "*,3cycle,*")])
1406 (define_expand "movhi"
1407 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1408 (match_operand:HI 1 "general_operand" ""))]
1411 if (sparc_expand_move (HImode, operands))
1415 (define_insn "*movhi_insn"
1416 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1417 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1418 "(register_operand (operands[0], HImode)
1419 || register_or_zero_operand (operands[1], HImode))"
1422 sethi\t%%hi(%a1), %0
1425 [(set_attr "type" "*,*,load,store")
1426 (set_attr "us3load_type" "*,*,3cycle,*")])
1428 ;; We always work with constants here.
1429 (define_insn "*movhi_lo_sum"
1430 [(set (match_operand:HI 0 "register_operand" "=r")
1431 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1432 (match_operand:HI 2 "small_int_operand" "I")))]
1436 (define_expand "movsi"
1437 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1438 (match_operand:SI 1 "general_operand" ""))]
1441 if (sparc_expand_move (SImode, operands))
1445 (define_insn "*movsi_insn"
1446 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1447 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1448 "register_operand (operands[0], SImode)
1449 || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1452 sethi\t%%hi(%a1), %0
1462 [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1463 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1465 (define_insn "*movsi_lo_sum"
1466 [(set (match_operand:SI 0 "register_operand" "=r")
1467 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1468 (match_operand:SI 2 "immediate_operand" "in")))]
1470 "or\t%1, %%lo(%a2), %0")
1472 (define_insn "*movsi_high"
1473 [(set (match_operand:SI 0 "register_operand" "=r")
1474 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1476 "sethi\t%%hi(%a1), %0")
1478 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1479 ;; so that CSE won't optimize the address computation away.
1480 (define_insn "movsi_lo_sum_pic"
1481 [(set (match_operand:SI 0 "register_operand" "=r")
1482 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1483 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1486 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1487 return "xor\t%1, %%gdop_lox10(%a2), %0";
1489 return "or\t%1, %%lo(%a2), %0";
1493 (define_insn "movsi_high_pic"
1494 [(set (match_operand:SI 0 "register_operand" "=r")
1495 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1496 "flag_pic && check_pic (1)"
1498 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1499 return "sethi\t%%gdop_hix22(%a1), %0";
1501 return "sethi\t%%hi(%a1), %0";
1505 (define_insn "movsi_pic_gotdata_op"
1506 [(set (match_operand:SI 0 "register_operand" "=r")
1507 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1508 (match_operand:SI 2 "register_operand" "r")
1509 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1510 "flag_pic && check_pic (1)"
1512 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1513 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1515 return "ld\t[%1 + %2], %0";
1518 [(set_attr "type" "load")])
1520 (define_expand "movsi_pic_label_ref"
1521 [(set (match_dup 3) (high:SI
1522 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1523 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1524 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1525 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1526 (set (match_operand:SI 0 "register_operand" "=r")
1527 (minus:SI (match_dup 5) (match_dup 4)))]
1530 crtl->uses_pic_offset_table = 1;
1531 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1532 if (!can_create_pseudo_p ())
1534 operands[3] = operands[0];
1535 operands[4] = operands[0];
1539 operands[3] = gen_reg_rtx (SImode);
1540 operands[4] = gen_reg_rtx (SImode);
1542 operands[5] = pic_offset_table_rtx;
1545 (define_insn "*movsi_high_pic_label_ref"
1546 [(set (match_operand:SI 0 "register_operand" "=r")
1548 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1549 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1551 "sethi\t%%hi(%a2-(%a1-.)), %0")
1553 (define_insn "*movsi_lo_sum_pic_label_ref"
1554 [(set (match_operand:SI 0 "register_operand" "=r")
1555 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1556 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1557 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1559 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1561 ;; Set up the PIC register for VxWorks.
1563 (define_expand "vxworks_load_got"
1565 (high:SI (match_dup 1)))
1567 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1569 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1570 "TARGET_VXWORKS_RTP"
1572 operands[0] = pic_offset_table_rtx;
1573 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1574 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1577 (define_expand "movdi"
1578 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1579 (match_operand:DI 1 "general_operand" ""))]
1582 if (sparc_expand_move (DImode, operands))
1586 ;; Be careful, fmovd does not exist when !v9.
1587 ;; We match MEM moves directly when we have correct even
1588 ;; numbered registers, but fall into splits otherwise.
1589 ;; The constraint ordering here is really important to
1590 ;; avoid insane problems in reload, especially for patterns
1593 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1594 ;; (const_int -5016)))
1598 (define_insn "*movdi_insn_sp32"
1599 [(set (match_operand:DI 0 "nonimmediate_operand"
1600 "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e, r,?*f,?*e,?W,b,b")
1601 (match_operand:DI 1 "input_operand"
1602 " J,J,U,T,r,o,i,r,*f, T, o,*f, *e, *e,?*f, r, W,*e,J,P"))]
1604 && (register_operand (operands[0], DImode)
1605 || register_or_zero_operand (operands[1], DImode))"
1627 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl")
1628 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1629 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1630 (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
1632 (define_insn "*movdi_insn_sp64"
1633 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1634 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,*e, r, *e, W,*e,J,P"))]
1636 && (register_operand (operands[0], DImode)
1637 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1640 sethi\t%%hi(%a1), %0
1650 [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1651 (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1652 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1654 (define_expand "movdi_pic_label_ref"
1655 [(set (match_dup 3) (high:DI
1656 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1657 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1658 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1659 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1660 (set (match_operand:DI 0 "register_operand" "=r")
1661 (minus:DI (match_dup 5) (match_dup 4)))]
1662 "TARGET_ARCH64 && flag_pic"
1664 crtl->uses_pic_offset_table = 1;
1665 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1666 if (!can_create_pseudo_p ())
1668 operands[3] = operands[0];
1669 operands[4] = operands[0];
1673 operands[3] = gen_reg_rtx (DImode);
1674 operands[4] = gen_reg_rtx (DImode);
1676 operands[5] = pic_offset_table_rtx;
1679 (define_insn "*movdi_high_pic_label_ref"
1680 [(set (match_operand:DI 0 "register_operand" "=r")
1682 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1683 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1684 "TARGET_ARCH64 && flag_pic"
1685 "sethi\t%%hi(%a2-(%a1-.)), %0")
1687 (define_insn "*movdi_lo_sum_pic_label_ref"
1688 [(set (match_operand:DI 0 "register_operand" "=r")
1689 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1690 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1691 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1692 "TARGET_ARCH64 && flag_pic"
1693 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1695 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1696 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1698 (define_insn "movdi_lo_sum_pic"
1699 [(set (match_operand:DI 0 "register_operand" "=r")
1700 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1701 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1702 "TARGET_ARCH64 && flag_pic"
1704 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1705 return "xor\t%1, %%gdop_lox10(%a2), %0";
1707 return "or\t%1, %%lo(%a2), %0";
1711 (define_insn "movdi_high_pic"
1712 [(set (match_operand:DI 0 "register_operand" "=r")
1713 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1714 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1716 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1717 return "sethi\t%%gdop_hix22(%a1), %0";
1719 return "sethi\t%%hi(%a1), %0";
1723 (define_insn "movdi_pic_gotdata_op"
1724 [(set (match_operand:DI 0 "register_operand" "=r")
1725 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1726 (match_operand:DI 2 "register_operand" "r")
1727 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1728 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1730 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1731 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1733 return "ldx\t[%1 + %2], %0";
1736 [(set_attr "type" "load")])
1738 (define_insn "*sethi_di_medlow_embmedany_pic"
1739 [(set (match_operand:DI 0 "register_operand" "=r")
1740 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1741 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1742 "sethi\t%%hi(%a1), %0")
1744 (define_insn "*sethi_di_medlow"
1745 [(set (match_operand:DI 0 "register_operand" "=r")
1746 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1747 "TARGET_CM_MEDLOW && check_pic (1)"
1748 "sethi\t%%hi(%a1), %0")
1750 (define_insn "*losum_di_medlow"
1751 [(set (match_operand:DI 0 "register_operand" "=r")
1752 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1753 (match_operand:DI 2 "symbolic_operand" "")))]
1755 "or\t%1, %%lo(%a2), %0")
1757 (define_insn "seth44"
1758 [(set (match_operand:DI 0 "register_operand" "=r")
1759 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1761 "sethi\t%%h44(%a1), %0")
1763 (define_insn "setm44"
1764 [(set (match_operand:DI 0 "register_operand" "=r")
1765 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1766 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1768 "or\t%1, %%m44(%a2), %0")
1770 (define_insn "setl44"
1771 [(set (match_operand:DI 0 "register_operand" "=r")
1772 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1773 (match_operand:DI 2 "symbolic_operand" "")))]
1775 "or\t%1, %%l44(%a2), %0")
1777 (define_insn "sethh"
1778 [(set (match_operand:DI 0 "register_operand" "=r")
1779 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1781 "sethi\t%%hh(%a1), %0")
1783 (define_insn "setlm"
1784 [(set (match_operand:DI 0 "register_operand" "=r")
1785 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1787 "sethi\t%%lm(%a1), %0")
1789 (define_insn "sethm"
1790 [(set (match_operand:DI 0 "register_operand" "=r")
1791 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1792 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1794 "or\t%1, %%hm(%a2), %0")
1796 (define_insn "setlo"
1797 [(set (match_operand:DI 0 "register_operand" "=r")
1798 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1799 (match_operand:DI 2 "symbolic_operand" "")))]
1801 "or\t%1, %%lo(%a2), %0")
1803 (define_insn "embmedany_sethi"
1804 [(set (match_operand:DI 0 "register_operand" "=r")
1805 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1806 "TARGET_CM_EMBMEDANY && check_pic (1)"
1807 "sethi\t%%hi(%a1), %0")
1809 (define_insn "embmedany_losum"
1810 [(set (match_operand:DI 0 "register_operand" "=r")
1811 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1812 (match_operand:DI 2 "data_segment_operand" "")))]
1813 "TARGET_CM_EMBMEDANY"
1814 "add\t%1, %%lo(%a2), %0")
1816 (define_insn "embmedany_brsum"
1817 [(set (match_operand:DI 0 "register_operand" "=r")
1818 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1819 "TARGET_CM_EMBMEDANY"
1822 (define_insn "embmedany_textuhi"
1823 [(set (match_operand:DI 0 "register_operand" "=r")
1824 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1825 "TARGET_CM_EMBMEDANY && check_pic (1)"
1826 "sethi\t%%uhi(%a1), %0")
1828 (define_insn "embmedany_texthi"
1829 [(set (match_operand:DI 0 "register_operand" "=r")
1830 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1831 "TARGET_CM_EMBMEDANY && check_pic (1)"
1832 "sethi\t%%hi(%a1), %0")
1834 (define_insn "embmedany_textulo"
1835 [(set (match_operand:DI 0 "register_operand" "=r")
1836 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1837 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1838 "TARGET_CM_EMBMEDANY"
1839 "or\t%1, %%ulo(%a2), %0")
1841 (define_insn "embmedany_textlo"
1842 [(set (match_operand:DI 0 "register_operand" "=r")
1843 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1844 (match_operand:DI 2 "text_segment_operand" "")))]
1845 "TARGET_CM_EMBMEDANY"
1846 "or\t%1, %%lo(%a2), %0")
1848 ;; Now some patterns to help reload out a bit.
1849 (define_expand "reload_indi"
1850 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1851 (match_operand:DI 1 "immediate_operand" "")
1852 (match_operand:TI 2 "register_operand" "=&r")])]
1854 || TARGET_CM_EMBMEDANY)
1857 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1861 (define_expand "reload_outdi"
1862 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1863 (match_operand:DI 1 "immediate_operand" "")
1864 (match_operand:TI 2 "register_operand" "=&r")])]
1866 || TARGET_CM_EMBMEDANY)
1869 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1873 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1875 [(set (match_operand:DI 0 "register_operand" "")
1876 (match_operand:DI 1 "const_int_operand" ""))]
1878 && ((GET_CODE (operands[0]) == REG
1879 && SPARC_INT_REG_P (REGNO (operands[0])))
1880 || (GET_CODE (operands[0]) == SUBREG
1881 && GET_CODE (SUBREG_REG (operands[0])) == REG
1882 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))
1883 && reload_completed"
1884 [(clobber (const_int 0))]
1886 #if HOST_BITS_PER_WIDE_INT == 32
1887 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1888 (INTVAL (operands[1]) < 0) ?
1891 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1894 HOST_WIDE_INT low, high;
1896 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1897 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1898 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1900 /* Slick... but this trick loses if this subreg constant part
1901 can be done in one insn. */
1903 && ! SPARC_SETHI32_P (high)
1904 && ! SPARC_SIMM13_P (high))
1905 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1906 gen_highpart (SImode, operands[0])));
1908 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1914 [(set (match_operand:DI 0 "register_operand" "")
1915 (match_operand:DI 1 "const_double_operand" ""))]
1919 && ((GET_CODE (operands[0]) == REG
1920 && SPARC_INT_REG_P (REGNO (operands[0])))
1921 || (GET_CODE (operands[0]) == SUBREG
1922 && GET_CODE (SUBREG_REG (operands[0])) == REG
1923 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
1924 [(clobber (const_int 0))]
1926 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1927 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1929 /* Slick... but this trick loses if this subreg constant part
1930 can be done in one insn. */
1931 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1932 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1933 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1935 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1936 gen_highpart (SImode, operands[0])));
1940 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1941 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1947 [(set (match_operand:DI 0 "register_operand" "")
1948 (match_operand:DI 1 "register_operand" ""))]
1952 && sparc_split_regreg_legitimate (operands[0],
1954 [(clobber (const_int 0))]
1956 rtx set_dest = operands[0];
1957 rtx set_src = operands[1];
1961 dest1 = gen_highpart (SImode, set_dest);
1962 dest2 = gen_lowpart (SImode, set_dest);
1963 src1 = gen_highpart (SImode, set_src);
1964 src2 = gen_lowpart (SImode, set_src);
1966 /* Now emit using the real source and destination we found, swapping
1967 the order if we detect overlap. */
1968 if (reg_overlap_mentioned_p (dest1, src2))
1970 emit_insn (gen_movsi (dest2, src2));
1971 emit_insn (gen_movsi (dest1, src1));
1975 emit_insn (gen_movsi (dest1, src1));
1976 emit_insn (gen_movsi (dest2, src2));
1981 ;; Now handle the cases of memory moves from/to non-even
1982 ;; DI mode register pairs.
1984 [(set (match_operand:DI 0 "register_operand" "")
1985 (match_operand:DI 1 "memory_operand" ""))]
1988 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1989 [(clobber (const_int 0))]
1991 rtx word0 = adjust_address (operands[1], SImode, 0);
1992 rtx word1 = adjust_address (operands[1], SImode, 4);
1993 rtx high_part = gen_highpart (SImode, operands[0]);
1994 rtx low_part = gen_lowpart (SImode, operands[0]);
1996 if (reg_overlap_mentioned_p (high_part, word1))
1998 emit_insn (gen_movsi (low_part, word1));
1999 emit_insn (gen_movsi (high_part, word0));
2003 emit_insn (gen_movsi (high_part, word0));
2004 emit_insn (gen_movsi (low_part, word1));
2010 [(set (match_operand:DI 0 "memory_operand" "")
2011 (match_operand:DI 1 "register_operand" ""))]
2014 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2015 [(clobber (const_int 0))]
2017 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2018 gen_highpart (SImode, operands[1])));
2019 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2020 gen_lowpart (SImode, operands[1])));
2025 [(set (match_operand:DI 0 "memory_operand" "")
2026 (match_operand:DI 1 "const_zero_operand" ""))]
2030 && ! mem_min_alignment (operands[0], 8)))
2031 && offsettable_memref_p (operands[0])"
2032 [(clobber (const_int 0))]
2034 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2035 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2039 (define_expand "movti"
2040 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2041 (match_operand:TI 1 "general_operand" ""))]
2044 if (sparc_expand_move (TImode, operands))
2048 ;; We need to prevent reload from splitting TImode moves, because it
2049 ;; might decide to overwrite a pointer with the value it points to.
2050 ;; In that case we have to do the loads in the appropriate order so
2051 ;; that the pointer is not destroyed too early.
2053 (define_insn "*movti_insn_sp64"
2054 [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b")
2055 (match_operand:TI 1 "input_operand" "roJ,rJ, eo, e,J"))]
2057 && ! TARGET_HARD_QUAD
2058 && (register_operand (operands[0], TImode)
2059 || register_or_zero_operand (operands[1], TImode))"
2061 [(set_attr "length" "2,2,2,2,2")
2062 (set_attr "cpu_feature" "*,*,fpu,fpu,vis")])
2064 (define_insn "*movti_insn_sp64_hq"
2065 [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b")
2066 (match_operand:TI 1 "input_operand" "roJ,rJ, e, m, e,J"))]
2069 && (register_operand (operands[0], TImode)
2070 || register_or_zero_operand (operands[1], TImode))"
2078 [(set_attr "type" "*,*,fpmove,fpload,fpstore,*")
2079 (set_attr "length" "2,2,*,*,*,2")])
2081 ;; Now all the splits to handle multi-insn TI mode moves.
2083 [(set (match_operand:TI 0 "register_operand" "")
2084 (match_operand:TI 1 "register_operand" ""))]
2087 && ! TARGET_HARD_QUAD)
2088 || (! fp_register_operand (operands[0], TImode)
2089 && ! fp_register_operand (operands[1], TImode)))"
2090 [(clobber (const_int 0))]
2092 rtx set_dest = operands[0];
2093 rtx set_src = operands[1];
2097 dest1 = gen_highpart (DImode, set_dest);
2098 dest2 = gen_lowpart (DImode, set_dest);
2099 src1 = gen_highpart (DImode, set_src);
2100 src2 = gen_lowpart (DImode, set_src);
2102 /* Now emit using the real source and destination we found, swapping
2103 the order if we detect overlap. */
2104 if (reg_overlap_mentioned_p (dest1, src2))
2106 emit_insn (gen_movdi (dest2, src2));
2107 emit_insn (gen_movdi (dest1, src1));
2111 emit_insn (gen_movdi (dest1, src1));
2112 emit_insn (gen_movdi (dest2, src2));
2118 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2119 (match_operand:TI 1 "const_zero_operand" ""))]
2121 [(clobber (const_int 0))]
2123 rtx set_dest = operands[0];
2126 switch (GET_CODE (set_dest))
2129 dest1 = gen_highpart (DImode, set_dest);
2130 dest2 = gen_lowpart (DImode, set_dest);
2133 dest1 = adjust_address (set_dest, DImode, 0);
2134 dest2 = adjust_address (set_dest, DImode, 8);
2140 emit_insn (gen_movdi (dest1, const0_rtx));
2141 emit_insn (gen_movdi (dest2, const0_rtx));
2146 [(set (match_operand:TI 0 "register_operand" "")
2147 (match_operand:TI 1 "memory_operand" ""))]
2149 && offsettable_memref_p (operands[1])
2150 && (! TARGET_HARD_QUAD
2151 || ! fp_register_operand (operands[0], TImode))"
2152 [(clobber (const_int 0))]
2154 rtx word0 = adjust_address (operands[1], DImode, 0);
2155 rtx word1 = adjust_address (operands[1], DImode, 8);
2156 rtx set_dest, dest1, dest2;
2158 set_dest = operands[0];
2160 dest1 = gen_highpart (DImode, set_dest);
2161 dest2 = gen_lowpart (DImode, set_dest);
2163 /* Now output, ordering such that we don't clobber any registers
2164 mentioned in the address. */
2165 if (reg_overlap_mentioned_p (dest1, word1))
2168 emit_insn (gen_movdi (dest2, word1));
2169 emit_insn (gen_movdi (dest1, word0));
2173 emit_insn (gen_movdi (dest1, word0));
2174 emit_insn (gen_movdi (dest2, word1));
2180 [(set (match_operand:TI 0 "memory_operand" "")
2181 (match_operand:TI 1 "register_operand" ""))]
2183 && offsettable_memref_p (operands[0])
2184 && (! TARGET_HARD_QUAD
2185 || ! fp_register_operand (operands[1], TImode))"
2186 [(clobber (const_int 0))]
2188 rtx set_src = operands[1];
2190 emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0),
2191 gen_highpart (DImode, set_src)));
2192 emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8),
2193 gen_lowpart (DImode, set_src)));
2198 ;; Floating point move instructions
2200 (define_expand "movsf"
2201 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2202 (match_operand:SF 1 "general_operand" ""))]
2205 if (sparc_expand_move (SFmode, operands))
2209 (define_insn "*movsf_insn"
2210 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m, m")
2211 (match_operand:SF 1 "input_operand" "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2212 "(register_operand (operands[0], SFmode)
2213 || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2215 if (GET_CODE (operands[1]) == CONST_DOUBLE
2216 && (which_alternative == 3
2217 || which_alternative == 4
2218 || which_alternative == 5))
2223 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2224 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2225 operands[1] = GEN_INT (i);
2228 switch (which_alternative)
2231 return "fzeros\t%0";
2235 return "fmovs\t%1, %0";
2237 return "mov\t%1, %0";
2239 return "sethi\t%%hi(%a1), %0";
2243 return "movstouw\t%1, %0";
2245 return "movwtos\t%1, %0";
2248 return "ld\t%1, %0";
2251 return "st\t%r1, %0";
2256 [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store")
2257 (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2259 ;; The following 3 patterns build SFmode constants in integer registers.
2261 (define_insn "*movsf_lo_sum"
2262 [(set (match_operand:SF 0 "register_operand" "=r")
2263 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2264 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2270 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2271 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2272 operands[2] = GEN_INT (i);
2273 return "or\t%1, %%lo(%a2), %0";
2276 (define_insn "*movsf_high"
2277 [(set (match_operand:SF 0 "register_operand" "=r")
2278 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2284 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2285 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2286 operands[1] = GEN_INT (i);
2287 return "sethi\t%%hi(%1), %0";
2291 [(set (match_operand:SF 0 "register_operand" "")
2292 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2293 "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2294 [(set (match_dup 0) (high:SF (match_dup 1)))
2295 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2297 (define_expand "movdf"
2298 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2299 (match_operand:DF 1 "general_operand" ""))]
2302 if (sparc_expand_move (DFmode, operands))
2306 (define_insn "*movdf_insn_sp32"
2307 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f, e,T,W,U,T, f, *r, o,o")
2308 (match_operand:DF 1 "input_operand" "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))]
2310 && (register_operand (operands[0], DFmode)
2311 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2328 [(set_attr "type" "visl,visl,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*")
2329 (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2")
2330 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2331 (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")])
2333 (define_insn "*movdf_insn_sp64"
2334 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r")
2335 (match_operand:DF 1 "input_operand" "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2337 && (register_operand (operands[0], DFmode)
2338 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2351 [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*")
2352 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2353 (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2354 (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2356 ;; This pattern builds DFmode constants in integer registers.
2358 [(set (match_operand:DF 0 "register_operand" "")
2359 (match_operand:DF 1 "const_double_operand" ""))]
2360 "REG_P (operands[0])
2361 && SPARC_INT_REG_P (REGNO (operands[0]))
2362 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2363 && reload_completed"
2364 [(clobber (const_int 0))]
2366 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2370 #if HOST_BITS_PER_WIDE_INT == 32
2373 enum machine_mode mode = GET_MODE (operands[1]);
2374 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2375 emit_insn (gen_movdi (operands[0], tem));
2380 enum machine_mode mode = GET_MODE (operands[1]);
2381 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2382 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2384 gcc_assert (GET_CODE (hi) == CONST_INT);
2385 gcc_assert (GET_CODE (lo) == CONST_INT);
2387 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2389 /* Slick... but this trick loses if this subreg constant part
2390 can be done in one insn. */
2392 && ! SPARC_SETHI32_P (INTVAL (hi))
2393 && ! SPARC_SIMM13_P (INTVAL (hi)))
2395 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2396 gen_highpart (SImode, operands[0])));
2400 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2406 ;; Ok, now the splits to handle all the multi insn and
2407 ;; mis-aligned memory address cases.
2408 ;; In these splits please take note that we must be
2409 ;; careful when V9 but not ARCH64 because the integer
2410 ;; register DFmode cases must be handled.
2412 [(set (match_operand:DF 0 "register_operand" "")
2413 (match_operand:DF 1 "register_operand" ""))]
2416 && sparc_split_regreg_legitimate (operands[0],
2418 && reload_completed"
2419 [(clobber (const_int 0))]
2421 rtx set_dest = operands[0];
2422 rtx set_src = operands[1];
2426 dest1 = gen_highpart (SFmode, set_dest);
2427 dest2 = gen_lowpart (SFmode, set_dest);
2428 src1 = gen_highpart (SFmode, set_src);
2429 src2 = gen_lowpart (SFmode, set_src);
2431 /* Now emit using the real source and destination we found, swapping
2432 the order if we detect overlap. */
2433 if (reg_overlap_mentioned_p (dest1, src2))
2435 emit_move_insn_1 (dest2, src2);
2436 emit_move_insn_1 (dest1, src1);
2440 emit_move_insn_1 (dest1, src1);
2441 emit_move_insn_1 (dest2, src2);
2447 [(set (match_operand:DF 0 "register_operand" "")
2448 (match_operand:DF 1 "memory_operand" ""))]
2451 && (((REGNO (operands[0]) % 2) != 0)
2452 || ! mem_min_alignment (operands[1], 8))
2453 && offsettable_memref_p (operands[1])"
2454 [(clobber (const_int 0))]
2458 word0 = adjust_address (operands[1], SFmode, 0);
2459 word1 = adjust_address (operands[1], SFmode, 4);
2461 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2463 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2464 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2468 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2469 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2475 [(set (match_operand:DF 0 "memory_operand" "")
2476 (match_operand:DF 1 "register_operand" ""))]
2479 && (((REGNO (operands[1]) % 2) != 0)
2480 || ! mem_min_alignment (operands[0], 8))
2481 && offsettable_memref_p (operands[0])"
2482 [(clobber (const_int 0))]
2486 word0 = adjust_address (operands[0], SFmode, 0);
2487 word1 = adjust_address (operands[0], SFmode, 4);
2489 emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2490 emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2495 [(set (match_operand:DF 0 "memory_operand" "")
2496 (match_operand:DF 1 "const_zero_operand" ""))]
2500 && ! mem_min_alignment (operands[0], 8)))
2501 && offsettable_memref_p (operands[0])"
2502 [(clobber (const_int 0))]
2506 dest1 = adjust_address (operands[0], SFmode, 0);
2507 dest2 = adjust_address (operands[0], SFmode, 4);
2509 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2510 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2515 [(set (match_operand:DF 0 "register_operand" "")
2516 (match_operand:DF 1 "const_zero_operand" ""))]
2519 && ((GET_CODE (operands[0]) == REG
2520 && SPARC_INT_REG_P (REGNO (operands[0])))
2521 || (GET_CODE (operands[0]) == SUBREG
2522 && GET_CODE (SUBREG_REG (operands[0])) == REG
2523 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2524 [(clobber (const_int 0))]
2526 rtx set_dest = operands[0];
2529 dest1 = gen_highpart (SFmode, set_dest);
2530 dest2 = gen_lowpart (SFmode, set_dest);
2531 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2532 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2536 (define_expand "movtf"
2537 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2538 (match_operand:TF 1 "general_operand" ""))]
2541 if (sparc_expand_move (TFmode, operands))
2545 (define_insn "*movtf_insn_sp32"
2546 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,U, r")
2547 (match_operand:TF 1 "input_operand" " G,oe,e,rGU,o,roG"))]
2549 && (register_operand (operands[0], TFmode)
2550 || register_or_zero_operand (operands[1], TFmode))"
2552 [(set_attr "length" "4,4,4,4,4,4")
2553 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")])
2555 (define_insn "*movtf_insn_sp64"
2556 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o, r")
2557 (match_operand:TF 1 "input_operand" "G,oe,e,rG,roG"))]
2559 && ! TARGET_HARD_QUAD
2560 && (register_operand (operands[0], TFmode)
2561 || register_or_zero_operand (operands[1], TFmode))"
2563 [(set_attr "length" "2,2,2,2,2")
2564 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2566 (define_insn "*movtf_insn_sp64_hq"
2567 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o, r")
2568 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2571 && (register_operand (operands[0], TFmode)
2572 || register_or_zero_operand (operands[1], TFmode))"
2580 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2581 (set_attr "length" "2,*,*,*,2,2")])
2583 ;; Now all the splits to handle multi-insn TF mode moves.
2585 [(set (match_operand:TF 0 "register_operand" "")
2586 (match_operand:TF 1 "register_operand" ""))]
2590 && ! TARGET_HARD_QUAD)
2591 || (! fp_register_operand (operands[0], TFmode)
2592 && ! fp_register_operand (operands[1], TFmode)))"
2593 [(clobber (const_int 0))]
2595 rtx set_dest = operands[0];
2596 rtx set_src = operands[1];
2600 dest1 = gen_df_reg (set_dest, 0);
2601 dest2 = gen_df_reg (set_dest, 1);
2602 src1 = gen_df_reg (set_src, 0);
2603 src2 = gen_df_reg (set_src, 1);
2605 /* Now emit using the real source and destination we found, swapping
2606 the order if we detect overlap. */
2607 if (reg_overlap_mentioned_p (dest1, src2))
2609 emit_insn (gen_movdf (dest2, src2));
2610 emit_insn (gen_movdf (dest1, src1));
2614 emit_insn (gen_movdf (dest1, src1));
2615 emit_insn (gen_movdf (dest2, src2));
2621 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2622 (match_operand:TF 1 "const_zero_operand" ""))]
2624 [(clobber (const_int 0))]
2626 rtx set_dest = operands[0];
2629 switch (GET_CODE (set_dest))
2632 dest1 = gen_df_reg (set_dest, 0);
2633 dest2 = gen_df_reg (set_dest, 1);
2636 dest1 = adjust_address (set_dest, DFmode, 0);
2637 dest2 = adjust_address (set_dest, DFmode, 8);
2643 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2644 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2649 [(set (match_operand:TF 0 "register_operand" "")
2650 (match_operand:TF 1 "memory_operand" ""))]
2652 && offsettable_memref_p (operands[1])
2654 || ! TARGET_HARD_QUAD
2655 || ! fp_register_operand (operands[0], TFmode)))"
2656 [(clobber (const_int 0))]
2658 rtx word0 = adjust_address (operands[1], DFmode, 0);
2659 rtx word1 = adjust_address (operands[1], DFmode, 8);
2660 rtx set_dest, dest1, dest2;
2662 set_dest = operands[0];
2664 dest1 = gen_df_reg (set_dest, 0);
2665 dest2 = gen_df_reg (set_dest, 1);
2667 /* Now output, ordering such that we don't clobber any registers
2668 mentioned in the address. */
2669 if (reg_overlap_mentioned_p (dest1, word1))
2672 emit_insn (gen_movdf (dest2, word1));
2673 emit_insn (gen_movdf (dest1, word0));
2677 emit_insn (gen_movdf (dest1, word0));
2678 emit_insn (gen_movdf (dest2, word1));
2684 [(set (match_operand:TF 0 "memory_operand" "")
2685 (match_operand:TF 1 "register_operand" ""))]
2687 && offsettable_memref_p (operands[0])
2689 || ! TARGET_HARD_QUAD
2690 || ! fp_register_operand (operands[1], TFmode)))"
2691 [(clobber (const_int 0))]
2693 rtx set_src = operands[1];
2695 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2696 gen_df_reg (set_src, 0)));
2697 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2698 gen_df_reg (set_src, 1)));
2703 ;; SPARC-V9 conditional move instructions
2705 ;; We can handle larger constants here for some flavors, but for now we keep
2706 ;; it simple and only allow those constants supported by all flavors.
2707 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2708 ;; 3 contains the constant if one is present, but we handle either for
2709 ;; generality (sparc.c puts a constant in operand 2).
2711 ;; Our instruction patterns, on the other hand, canonicalize such that
2712 ;; operand 3 must be the set destination.
2714 (define_expand "mov<I:mode>cc"
2715 [(set (match_operand:I 0 "register_operand" "")
2716 (if_then_else:I (match_operand 1 "comparison_operator" "")
2717 (match_operand:I 2 "arith10_operand" "")
2718 (match_operand:I 3 "arith10_operand" "")))]
2719 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2721 if (! sparc_expand_conditional_move (<I:MODE>mode, operands))
2726 (define_expand "mov<F:mode>cc"
2727 [(set (match_operand:F 0 "register_operand" "")
2728 (if_then_else:F (match_operand 1 "comparison_operator" "")
2729 (match_operand:F 2 "register_operand" "")
2730 (match_operand:F 3 "register_operand" "")))]
2731 "TARGET_V9 && TARGET_FPU"
2733 if (! sparc_expand_conditional_move (<F:MODE>mode, operands))
2738 ;; Conditional move define_insns
2740 (define_insn "*mov<I:mode>_cc_v9"
2741 [(set (match_operand:I 0 "register_operand" "=r")
2742 (if_then_else:I (match_operator 1 "comparison_operator"
2743 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2745 (match_operand:I 3 "arith11_operand" "rL")
2746 (match_operand:I 4 "register_operand" "0")))]
2747 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2748 "mov%C1\t%x2, %3, %0"
2749 [(set_attr "type" "cmove")])
2751 (define_insn "*mov<I:mode>_cc_reg_sp64"
2752 [(set (match_operand:I 0 "register_operand" "=r")
2753 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2754 [(match_operand:DI 2 "register_operand" "r")
2756 (match_operand:I 3 "arith10_operand" "rM")
2757 (match_operand:I 4 "register_operand" "0")))]
2759 "movr%D1\t%2, %r3, %0"
2760 [(set_attr "type" "cmove")])
2762 (define_insn "*movsf_cc_v9"
2763 [(set (match_operand:SF 0 "register_operand" "=f")
2764 (if_then_else:SF (match_operator 1 "comparison_operator"
2765 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2767 (match_operand:SF 3 "register_operand" "f")
2768 (match_operand:SF 4 "register_operand" "0")))]
2769 "TARGET_V9 && TARGET_FPU"
2770 "fmovs%C1\t%x2, %3, %0"
2771 [(set_attr "type" "fpcmove")])
2773 (define_insn "*movsf_cc_reg_sp64"
2774 [(set (match_operand:SF 0 "register_operand" "=f")
2775 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2776 [(match_operand:DI 2 "register_operand" "r")
2778 (match_operand:SF 3 "register_operand" "f")
2779 (match_operand:SF 4 "register_operand" "0")))]
2780 "TARGET_ARCH64 && TARGET_FPU"
2781 "fmovrs%D1\t%2, %3, %0"
2782 [(set_attr "type" "fpcrmove")])
2784 ;; Named because invoked by movtf_cc_v9
2785 (define_insn "movdf_cc_v9"
2786 [(set (match_operand:DF 0 "register_operand" "=e")
2787 (if_then_else:DF (match_operator 1 "comparison_operator"
2788 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2790 (match_operand:DF 3 "register_operand" "e")
2791 (match_operand:DF 4 "register_operand" "0")))]
2792 "TARGET_V9 && TARGET_FPU"
2793 "fmovd%C1\t%x2, %3, %0"
2794 [(set_attr "type" "fpcmove")
2795 (set_attr "fptype" "double")])
2797 ;; Named because invoked by movtf_cc_reg_sp64
2798 (define_insn "movdf_cc_reg_sp64"
2799 [(set (match_operand:DF 0 "register_operand" "=e")
2800 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2801 [(match_operand:DI 2 "register_operand" "r")
2803 (match_operand:DF 3 "register_operand" "e")
2804 (match_operand:DF 4 "register_operand" "0")))]
2805 "TARGET_ARCH64 && TARGET_FPU"
2806 "fmovrd%D1\t%2, %3, %0"
2807 [(set_attr "type" "fpcrmove")
2808 (set_attr "fptype" "double")])
2810 (define_insn "*movtf_cc_hq_v9"
2811 [(set (match_operand:TF 0 "register_operand" "=e")
2812 (if_then_else:TF (match_operator 1 "comparison_operator"
2813 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2815 (match_operand:TF 3 "register_operand" "e")
2816 (match_operand:TF 4 "register_operand" "0")))]
2817 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2818 "fmovq%C1\t%x2, %3, %0"
2819 [(set_attr "type" "fpcmove")])
2821 (define_insn "*movtf_cc_reg_hq_sp64"
2822 [(set (match_operand:TF 0 "register_operand" "=e")
2823 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2824 [(match_operand:DI 2 "register_operand" "r")
2826 (match_operand:TF 3 "register_operand" "e")
2827 (match_operand:TF 4 "register_operand" "0")))]
2828 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2829 "fmovrq%D1\t%2, %3, %0"
2830 [(set_attr "type" "fpcrmove")])
2832 (define_insn_and_split "*movtf_cc_v9"
2833 [(set (match_operand:TF 0 "register_operand" "=e")
2834 (if_then_else:TF (match_operator 1 "comparison_operator"
2835 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2837 (match_operand:TF 3 "register_operand" "e")
2838 (match_operand:TF 4 "register_operand" "0")))]
2839 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2841 "&& reload_completed"
2842 [(clobber (const_int 0))]
2844 rtx set_dest = operands[0];
2845 rtx set_srca = operands[3];
2849 dest1 = gen_df_reg (set_dest, 0);
2850 dest2 = gen_df_reg (set_dest, 1);
2851 srca1 = gen_df_reg (set_srca, 0);
2852 srca2 = gen_df_reg (set_srca, 1);
2854 if (reg_overlap_mentioned_p (dest1, srca2))
2856 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2857 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2861 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2862 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2866 [(set_attr "length" "2")])
2868 (define_insn_and_split "*movtf_cc_reg_sp64"
2869 [(set (match_operand:TF 0 "register_operand" "=e")
2870 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2871 [(match_operand:DI 2 "register_operand" "r")
2873 (match_operand:TF 3 "register_operand" "e")
2874 (match_operand:TF 4 "register_operand" "0")))]
2875 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2877 "&& reload_completed"
2878 [(clobber (const_int 0))]
2880 rtx set_dest = operands[0];
2881 rtx set_srca = operands[3];
2885 dest1 = gen_df_reg (set_dest, 0);
2886 dest2 = gen_df_reg (set_dest, 1);
2887 srca1 = gen_df_reg (set_srca, 0);
2888 srca2 = gen_df_reg (set_srca, 1);
2890 if (reg_overlap_mentioned_p (dest1, srca2))
2892 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2893 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2897 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2898 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2902 [(set_attr "length" "2")])
2905 ;; Zero-extension instructions
2907 ;; These patterns originally accepted general_operands, however, slightly
2908 ;; better code is generated by only accepting register_operands, and then
2909 ;; letting combine generate the ldu[hb] insns.
2911 (define_expand "zero_extendhisi2"
2912 [(set (match_operand:SI 0 "register_operand" "")
2913 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2916 rtx temp = gen_reg_rtx (SImode);
2917 rtx shift_16 = GEN_INT (16);
2918 int op1_subbyte = 0;
2920 if (GET_CODE (operand1) == SUBREG)
2922 op1_subbyte = SUBREG_BYTE (operand1);
2923 op1_subbyte /= GET_MODE_SIZE (SImode);
2924 op1_subbyte *= GET_MODE_SIZE (SImode);
2925 operand1 = XEXP (operand1, 0);
2928 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2930 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2934 (define_insn "*zero_extendhisi2_insn"
2935 [(set (match_operand:SI 0 "register_operand" "=r")
2936 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2939 [(set_attr "type" "load")
2940 (set_attr "us3load_type" "3cycle")])
2942 (define_expand "zero_extendqihi2"
2943 [(set (match_operand:HI 0 "register_operand" "")
2944 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2948 (define_insn "*zero_extendqihi2_insn"
2949 [(set (match_operand:HI 0 "register_operand" "=r,r")
2950 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2951 "GET_CODE (operands[1]) != CONST_INT"
2955 [(set_attr "type" "*,load")
2956 (set_attr "us3load_type" "*,3cycle")])
2958 (define_expand "zero_extendqisi2"
2959 [(set (match_operand:SI 0 "register_operand" "")
2960 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2964 (define_insn "*zero_extendqisi2_insn"
2965 [(set (match_operand:SI 0 "register_operand" "=r,r")
2966 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2967 "GET_CODE (operands[1]) != CONST_INT"
2971 [(set_attr "type" "*,load")
2972 (set_attr "us3load_type" "*,3cycle")])
2974 (define_expand "zero_extendqidi2"
2975 [(set (match_operand:DI 0 "register_operand" "")
2976 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2980 (define_insn "*zero_extendqidi2_insn"
2981 [(set (match_operand:DI 0 "register_operand" "=r,r")
2982 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2983 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2987 [(set_attr "type" "*,load")
2988 (set_attr "us3load_type" "*,3cycle")])
2990 (define_expand "zero_extendhidi2"
2991 [(set (match_operand:DI 0 "register_operand" "")
2992 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2995 rtx temp = gen_reg_rtx (DImode);
2996 rtx shift_48 = GEN_INT (48);
2997 int op1_subbyte = 0;
2999 if (GET_CODE (operand1) == SUBREG)
3001 op1_subbyte = SUBREG_BYTE (operand1);
3002 op1_subbyte /= GET_MODE_SIZE (DImode);
3003 op1_subbyte *= GET_MODE_SIZE (DImode);
3004 operand1 = XEXP (operand1, 0);
3007 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3009 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3013 (define_insn "*zero_extendhidi2_insn"
3014 [(set (match_operand:DI 0 "register_operand" "=r")
3015 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3018 [(set_attr "type" "load")
3019 (set_attr "us3load_type" "3cycle")])
3021 ;; ??? Write truncdisi pattern using sra?
3023 (define_expand "zero_extendsidi2"
3024 [(set (match_operand:DI 0 "register_operand" "")
3025 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3029 (define_insn "*zero_extendsidi2_insn_sp64"
3030 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3031 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3033 && GET_CODE (operands[1]) != CONST_INT"
3038 [(set_attr "type" "shift,load,*")
3039 (set_attr "cpu_feature" "*,*,vis3")])
3041 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3042 [(set (match_operand:DI 0 "register_operand" "=r")
3043 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3046 "&& reload_completed"
3047 [(set (match_dup 2) (match_dup 3))
3048 (set (match_dup 4) (match_dup 5))]
3052 dest1 = gen_highpart (SImode, operands[0]);
3053 dest2 = gen_lowpart (SImode, operands[0]);
3055 /* Swap the order in case of overlap. */
3056 if (REGNO (dest1) == REGNO (operands[1]))
3058 operands[2] = dest2;
3059 operands[3] = operands[1];
3060 operands[4] = dest1;
3061 operands[5] = const0_rtx;
3065 operands[2] = dest1;
3066 operands[3] = const0_rtx;
3067 operands[4] = dest2;
3068 operands[5] = operands[1];
3071 [(set_attr "length" "2")])
3073 ;; Simplify comparisons of extended values.
3075 (define_insn "*cmp_zero_extendqisi2"
3076 [(set (reg:CC CC_REG)
3077 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3080 "andcc\t%0, 0xff, %%g0"
3081 [(set_attr "type" "compare")])
3083 (define_insn "*cmp_zero_qi"
3084 [(set (reg:CC CC_REG)
3085 (compare:CC (match_operand:QI 0 "register_operand" "r")
3088 "andcc\t%0, 0xff, %%g0"
3089 [(set_attr "type" "compare")])
3091 (define_insn "*cmp_zero_extendqisi2_set"
3092 [(set (reg:CC CC_REG)
3093 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3095 (set (match_operand:SI 0 "register_operand" "=r")
3096 (zero_extend:SI (match_dup 1)))]
3098 "andcc\t%1, 0xff, %0"
3099 [(set_attr "type" "compare")])
3101 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3102 [(set (reg:CC CC_REG)
3103 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3106 (set (match_operand:SI 0 "register_operand" "=r")
3107 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3109 "andcc\t%1, 0xff, %0"
3110 [(set_attr "type" "compare")])
3112 (define_insn "*cmp_zero_extendqidi2"
3113 [(set (reg:CCX CC_REG)
3114 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3117 "andcc\t%0, 0xff, %%g0"
3118 [(set_attr "type" "compare")])
3120 (define_insn "*cmp_zero_qi_sp64"
3121 [(set (reg:CCX CC_REG)
3122 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3125 "andcc\t%0, 0xff, %%g0"
3126 [(set_attr "type" "compare")])
3128 (define_insn "*cmp_zero_extendqidi2_set"
3129 [(set (reg:CCX CC_REG)
3130 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3132 (set (match_operand:DI 0 "register_operand" "=r")
3133 (zero_extend:DI (match_dup 1)))]
3135 "andcc\t%1, 0xff, %0"
3136 [(set_attr "type" "compare")])
3138 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3139 [(set (reg:CCX CC_REG)
3140 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3143 (set (match_operand:DI 0 "register_operand" "=r")
3144 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3146 "andcc\t%1, 0xff, %0"
3147 [(set_attr "type" "compare")])
3149 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3151 (define_insn "*cmp_siqi_trunc"
3152 [(set (reg:CC CC_REG)
3153 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3156 "andcc\t%0, 0xff, %%g0"
3157 [(set_attr "type" "compare")])
3159 (define_insn "*cmp_siqi_trunc_set"
3160 [(set (reg:CC CC_REG)
3161 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3163 (set (match_operand:QI 0 "register_operand" "=r")
3164 (subreg:QI (match_dup 1) 3))]
3166 "andcc\t%1, 0xff, %0"
3167 [(set_attr "type" "compare")])
3169 (define_insn "*cmp_diqi_trunc"
3170 [(set (reg:CC CC_REG)
3171 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3174 "andcc\t%0, 0xff, %%g0"
3175 [(set_attr "type" "compare")])
3177 (define_insn "*cmp_diqi_trunc_set"
3178 [(set (reg:CC CC_REG)
3179 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3181 (set (match_operand:QI 0 "register_operand" "=r")
3182 (subreg:QI (match_dup 1) 7))]
3184 "andcc\t%1, 0xff, %0"
3185 [(set_attr "type" "compare")])
3188 ;; Sign-extension instructions
3190 ;; These patterns originally accepted general_operands, however, slightly
3191 ;; better code is generated by only accepting register_operands, and then
3192 ;; letting combine generate the lds[hb] insns.
3194 (define_expand "extendhisi2"
3195 [(set (match_operand:SI 0 "register_operand" "")
3196 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3199 rtx temp = gen_reg_rtx (SImode);
3200 rtx shift_16 = GEN_INT (16);
3201 int op1_subbyte = 0;
3203 if (GET_CODE (operand1) == SUBREG)
3205 op1_subbyte = SUBREG_BYTE (operand1);
3206 op1_subbyte /= GET_MODE_SIZE (SImode);
3207 op1_subbyte *= GET_MODE_SIZE (SImode);
3208 operand1 = XEXP (operand1, 0);
3211 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3213 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3217 (define_insn "*sign_extendhisi2_insn"
3218 [(set (match_operand:SI 0 "register_operand" "=r")
3219 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3222 [(set_attr "type" "sload")
3223 (set_attr "us3load_type" "3cycle")])
3225 (define_expand "extendqihi2"
3226 [(set (match_operand:HI 0 "register_operand" "")
3227 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3230 rtx temp = gen_reg_rtx (SImode);
3231 rtx shift_24 = GEN_INT (24);
3232 int op1_subbyte = 0;
3233 int op0_subbyte = 0;
3235 if (GET_CODE (operand1) == SUBREG)
3237 op1_subbyte = SUBREG_BYTE (operand1);
3238 op1_subbyte /= GET_MODE_SIZE (SImode);
3239 op1_subbyte *= GET_MODE_SIZE (SImode);
3240 operand1 = XEXP (operand1, 0);
3242 if (GET_CODE (operand0) == SUBREG)
3244 op0_subbyte = SUBREG_BYTE (operand0);
3245 op0_subbyte /= GET_MODE_SIZE (SImode);
3246 op0_subbyte *= GET_MODE_SIZE (SImode);
3247 operand0 = XEXP (operand0, 0);
3249 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3251 if (GET_MODE (operand0) != SImode)
3252 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3253 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3257 (define_insn "*sign_extendqihi2_insn"
3258 [(set (match_operand:HI 0 "register_operand" "=r")
3259 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3262 [(set_attr "type" "sload")
3263 (set_attr "us3load_type" "3cycle")])
3265 (define_expand "extendqisi2"
3266 [(set (match_operand:SI 0 "register_operand" "")
3267 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3270 rtx temp = gen_reg_rtx (SImode);
3271 rtx shift_24 = GEN_INT (24);
3272 int op1_subbyte = 0;
3274 if (GET_CODE (operand1) == SUBREG)
3276 op1_subbyte = SUBREG_BYTE (operand1);
3277 op1_subbyte /= GET_MODE_SIZE (SImode);
3278 op1_subbyte *= GET_MODE_SIZE (SImode);
3279 operand1 = XEXP (operand1, 0);
3282 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3284 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3288 (define_insn "*sign_extendqisi2_insn"
3289 [(set (match_operand:SI 0 "register_operand" "=r")
3290 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3293 [(set_attr "type" "sload")
3294 (set_attr "us3load_type" "3cycle")])
3296 (define_expand "extendqidi2"
3297 [(set (match_operand:DI 0 "register_operand" "")
3298 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3301 rtx temp = gen_reg_rtx (DImode);
3302 rtx shift_56 = GEN_INT (56);
3303 int op1_subbyte = 0;
3305 if (GET_CODE (operand1) == SUBREG)
3307 op1_subbyte = SUBREG_BYTE (operand1);
3308 op1_subbyte /= GET_MODE_SIZE (DImode);
3309 op1_subbyte *= GET_MODE_SIZE (DImode);
3310 operand1 = XEXP (operand1, 0);
3313 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3315 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3319 (define_insn "*sign_extendqidi2_insn"
3320 [(set (match_operand:DI 0 "register_operand" "=r")
3321 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3324 [(set_attr "type" "sload")
3325 (set_attr "us3load_type" "3cycle")])
3327 (define_expand "extendhidi2"
3328 [(set (match_operand:DI 0 "register_operand" "")
3329 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3332 rtx temp = gen_reg_rtx (DImode);
3333 rtx shift_48 = GEN_INT (48);
3334 int op1_subbyte = 0;
3336 if (GET_CODE (operand1) == SUBREG)
3338 op1_subbyte = SUBREG_BYTE (operand1);
3339 op1_subbyte /= GET_MODE_SIZE (DImode);
3340 op1_subbyte *= GET_MODE_SIZE (DImode);
3341 operand1 = XEXP (operand1, 0);
3344 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3346 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3350 (define_insn "*sign_extendhidi2_insn"
3351 [(set (match_operand:DI 0 "register_operand" "=r")
3352 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3355 [(set_attr "type" "sload")
3356 (set_attr "us3load_type" "3cycle")])
3358 (define_expand "extendsidi2"
3359 [(set (match_operand:DI 0 "register_operand" "")
3360 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3364 (define_insn "*sign_extendsidi2_insn"
3365 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3366 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3372 [(set_attr "type" "shift,sload,*")
3373 (set_attr "us3load_type" "*,3cycle,*")
3374 (set_attr "cpu_feature" "*,*,vis3")])
3377 ;; Special pattern for optimizing bit-field compares. This is needed
3378 ;; because combine uses this as a canonical form.
3380 (define_insn "*cmp_zero_extract"
3381 [(set (reg:CC CC_REG)
3383 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3384 (match_operand:SI 1 "small_int_operand" "I")
3385 (match_operand:SI 2 "small_int_operand" "I"))
3387 "INTVAL (operands[2]) > 19"
3389 int len = INTVAL (operands[1]);
3390 int pos = 32 - INTVAL (operands[2]) - len;
3391 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3392 operands[1] = GEN_INT (mask);
3393 return "andcc\t%0, %1, %%g0";
3395 [(set_attr "type" "compare")])
3397 (define_insn "*cmp_zero_extract_sp64"
3398 [(set (reg:CCX CC_REG)
3400 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3401 (match_operand:SI 1 "small_int_operand" "I")
3402 (match_operand:SI 2 "small_int_operand" "I"))
3404 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3406 int len = INTVAL (operands[1]);
3407 int pos = 64 - INTVAL (operands[2]) - len;
3408 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3409 operands[1] = GEN_INT (mask);
3410 return "andcc\t%0, %1, %%g0";
3412 [(set_attr "type" "compare")])
3415 ;; Conversions between float, double and long double.
3417 (define_insn "extendsfdf2"
3418 [(set (match_operand:DF 0 "register_operand" "=e")
3420 (match_operand:SF 1 "register_operand" "f")))]
3423 [(set_attr "type" "fp")
3424 (set_attr "fptype" "double")])
3426 (define_expand "extendsftf2"
3427 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3429 (match_operand:SF 1 "register_operand" "")))]
3430 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3431 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3433 (define_insn "*extendsftf2_hq"
3434 [(set (match_operand:TF 0 "register_operand" "=e")
3436 (match_operand:SF 1 "register_operand" "f")))]
3437 "TARGET_FPU && TARGET_HARD_QUAD"
3439 [(set_attr "type" "fp")])
3441 (define_expand "extenddftf2"
3442 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3444 (match_operand:DF 1 "register_operand" "")))]
3445 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3446 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3448 (define_insn "*extenddftf2_hq"
3449 [(set (match_operand:TF 0 "register_operand" "=e")
3451 (match_operand:DF 1 "register_operand" "e")))]
3452 "TARGET_FPU && TARGET_HARD_QUAD"
3454 [(set_attr "type" "fp")])
3456 (define_insn "truncdfsf2"
3457 [(set (match_operand:SF 0 "register_operand" "=f")
3459 (match_operand:DF 1 "register_operand" "e")))]
3462 [(set_attr "type" "fp")
3463 (set_attr "fptype" "double")
3464 (set_attr "fptype_ut699" "single")])
3466 (define_expand "trunctfsf2"
3467 [(set (match_operand:SF 0 "register_operand" "")
3469 (match_operand:TF 1 "general_operand" "")))]
3470 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3471 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3473 (define_insn "*trunctfsf2_hq"
3474 [(set (match_operand:SF 0 "register_operand" "=f")
3476 (match_operand:TF 1 "register_operand" "e")))]
3477 "TARGET_FPU && TARGET_HARD_QUAD"
3479 [(set_attr "type" "fp")])
3481 (define_expand "trunctfdf2"
3482 [(set (match_operand:DF 0 "register_operand" "")
3484 (match_operand:TF 1 "general_operand" "")))]
3485 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3486 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3488 (define_insn "*trunctfdf2_hq"
3489 [(set (match_operand:DF 0 "register_operand" "=e")
3491 (match_operand:TF 1 "register_operand" "e")))]
3492 "TARGET_FPU && TARGET_HARD_QUAD"
3494 [(set_attr "type" "fp")])
3497 ;; Conversion between fixed point and floating point.
3499 (define_insn "floatsisf2"
3500 [(set (match_operand:SF 0 "register_operand" "=f")
3501 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3504 [(set_attr "type" "fp")
3505 (set_attr "fptype" "single")])
3507 (define_insn "floatsidf2"
3508 [(set (match_operand:DF 0 "register_operand" "=e")
3509 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3512 [(set_attr "type" "fp")
3513 (set_attr "fptype" "double")])
3515 (define_expand "floatsitf2"
3516 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3517 (float:TF (match_operand:SI 1 "register_operand" "")))]
3518 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3519 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3521 (define_insn "*floatsitf2_hq"
3522 [(set (match_operand:TF 0 "register_operand" "=e")
3523 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3524 "TARGET_FPU && TARGET_HARD_QUAD"
3526 [(set_attr "type" "fp")])
3528 (define_expand "floatunssitf2"
3529 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3530 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3531 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3532 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3534 ;; Now the same for 64 bit sources.
3536 (define_insn "floatdisf2"
3537 [(set (match_operand:SF 0 "register_operand" "=f")
3538 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3539 "TARGET_V9 && TARGET_FPU"
3541 [(set_attr "type" "fp")
3542 (set_attr "fptype" "double")])
3544 (define_expand "floatunsdisf2"
3545 [(use (match_operand:SF 0 "register_operand" ""))
3546 (use (match_operand:DI 1 "general_operand" ""))]
3547 "TARGET_ARCH64 && TARGET_FPU"
3548 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3550 (define_insn "floatdidf2"
3551 [(set (match_operand:DF 0 "register_operand" "=e")
3552 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3553 "TARGET_V9 && TARGET_FPU"
3555 [(set_attr "type" "fp")
3556 (set_attr "fptype" "double")])
3558 (define_expand "floatunsdidf2"
3559 [(use (match_operand:DF 0 "register_operand" ""))
3560 (use (match_operand:DI 1 "general_operand" ""))]
3561 "TARGET_ARCH64 && TARGET_FPU"
3562 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3564 (define_expand "floatditf2"
3565 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3566 (float:TF (match_operand:DI 1 "register_operand" "")))]
3567 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3568 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3570 (define_insn "*floatditf2_hq"
3571 [(set (match_operand:TF 0 "register_operand" "=e")
3572 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3573 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3575 [(set_attr "type" "fp")])
3577 (define_expand "floatunsditf2"
3578 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3579 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3580 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3581 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3583 ;; Convert a float to an actual integer.
3584 ;; Truncation is performed as part of the conversion.
3586 (define_insn "fix_truncsfsi2"
3587 [(set (match_operand:SI 0 "register_operand" "=f")
3588 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3591 [(set_attr "type" "fp")
3592 (set_attr "fptype" "single")])
3594 (define_insn "fix_truncdfsi2"
3595 [(set (match_operand:SI 0 "register_operand" "=f")
3596 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3599 [(set_attr "type" "fp")
3600 (set_attr "fptype" "double")
3601 (set_attr "fptype_ut699" "single")])
3603 (define_expand "fix_trunctfsi2"
3604 [(set (match_operand:SI 0 "register_operand" "")
3605 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3606 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3607 "emit_tfmode_cvt (FIX, operands); DONE;")
3609 (define_insn "*fix_trunctfsi2_hq"
3610 [(set (match_operand:SI 0 "register_operand" "=f")
3611 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3612 "TARGET_FPU && TARGET_HARD_QUAD"
3614 [(set_attr "type" "fp")])
3616 (define_expand "fixuns_trunctfsi2"
3617 [(set (match_operand:SI 0 "register_operand" "")
3618 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3619 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3620 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3622 ;; Now the same, for V9 targets
3624 (define_insn "fix_truncsfdi2"
3625 [(set (match_operand:DI 0 "register_operand" "=e")
3626 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3627 "TARGET_V9 && TARGET_FPU"
3629 [(set_attr "type" "fp")
3630 (set_attr "fptype" "double")])
3632 (define_expand "fixuns_truncsfdi2"
3633 [(use (match_operand:DI 0 "register_operand" ""))
3634 (use (match_operand:SF 1 "general_operand" ""))]
3635 "TARGET_ARCH64 && TARGET_FPU"
3636 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3638 (define_insn "fix_truncdfdi2"
3639 [(set (match_operand:DI 0 "register_operand" "=e")
3640 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3641 "TARGET_V9 && TARGET_FPU"
3643 [(set_attr "type" "fp")
3644 (set_attr "fptype" "double")])
3646 (define_expand "fixuns_truncdfdi2"
3647 [(use (match_operand:DI 0 "register_operand" ""))
3648 (use (match_operand:DF 1 "general_operand" ""))]
3649 "TARGET_ARCH64 && TARGET_FPU"
3650 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3652 (define_expand "fix_trunctfdi2"
3653 [(set (match_operand:DI 0 "register_operand" "")
3654 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3655 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3656 "emit_tfmode_cvt (FIX, operands); DONE;")
3658 (define_insn "*fix_trunctfdi2_hq"
3659 [(set (match_operand:DI 0 "register_operand" "=e")
3660 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3661 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3663 [(set_attr "type" "fp")])
3665 (define_expand "fixuns_trunctfdi2"
3666 [(set (match_operand:DI 0 "register_operand" "")
3667 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3668 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3669 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3672 ;; Integer addition/subtraction instructions.
3674 (define_expand "adddi3"
3675 [(set (match_operand:DI 0 "register_operand" "")
3676 (plus:DI (match_operand:DI 1 "register_operand" "")
3677 (match_operand:DI 2 "arith_double_add_operand" "")))]
3680 if (! TARGET_ARCH64)
3682 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3683 gen_rtx_SET (VOIDmode, operands[0],
3684 gen_rtx_PLUS (DImode, operands[1],
3686 gen_rtx_CLOBBER (VOIDmode,
3687 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3692 (define_insn_and_split "*adddi3_insn_sp32"
3693 [(set (match_operand:DI 0 "register_operand" "=&r")
3694 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3695 (match_operand:DI 2 "arith_double_operand" "rHI")))
3696 (clobber (reg:CC CC_REG))]
3699 "&& reload_completed"
3700 [(parallel [(set (reg:CC_NOOV CC_REG)
3701 (compare:CC_NOOV (plus:SI (match_dup 4)
3705 (plus:SI (match_dup 4) (match_dup 5)))])
3707 (plus:SI (plus:SI (match_dup 7)
3709 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3711 operands[3] = gen_lowpart (SImode, operands[0]);
3712 operands[4] = gen_lowpart (SImode, operands[1]);
3713 operands[5] = gen_lowpart (SImode, operands[2]);
3714 operands[6] = gen_highpart (SImode, operands[0]);
3715 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3716 #if HOST_BITS_PER_WIDE_INT == 32
3717 if (GET_CODE (operands[2]) == CONST_INT)
3719 if (INTVAL (operands[2]) < 0)
3720 operands[8] = constm1_rtx;
3722 operands[8] = const0_rtx;
3726 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3728 [(set_attr "length" "2")])
3730 ;; LTU here means "carry set"
3732 [(set (match_operand:SI 0 "register_operand" "=r")
3733 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3734 (match_operand:SI 2 "arith_operand" "rI"))
3735 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3738 [(set_attr "type" "ialuX")])
3740 (define_insn "addxc"
3741 [(set (match_operand:DI 0 "register_operand" "=r")
3742 (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
3743 (match_operand:DI 2 "register_or_zero_operand" "rJ"))
3744 (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3745 "TARGET_ARCH64 && TARGET_VIS3"
3746 "addxc\t%r1, %r2, %0"
3747 [(set_attr "type" "ialuX")])
3749 (define_insn_and_split "*addx_extend_sp32"
3750 [(set (match_operand:DI 0 "register_operand" "=r")
3751 (zero_extend:DI (plus:SI (plus:SI
3752 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3753 (match_operand:SI 2 "arith_operand" "rI"))
3754 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3757 "&& reload_completed"
3758 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3759 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3760 (set (match_dup 4) (const_int 0))]
3761 "operands[3] = gen_lowpart (SImode, operands[0]);
3762 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3763 [(set_attr "length" "2")])
3765 (define_insn "*addx_extend_sp64"
3766 [(set (match_operand:DI 0 "register_operand" "=r")
3767 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3768 (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3769 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3771 "addx\t%r1, %r2, %0"
3772 [(set_attr "type" "ialuX")])
3774 (define_insn "*addxc_trunc_sp64_vis3"
3775 [(set (match_operand:SI 0 "register_operand" "=r")
3776 (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3777 (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3778 (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3779 "TARGET_ARCH64 && TARGET_VIS3"
3780 "addxc\t%r1, %r2, %0"
3781 [(set_attr "type" "ialuX")])
3783 (define_insn_and_split "*adddi3_extend_sp32"
3784 [(set (match_operand:DI 0 "register_operand" "=r")
3785 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3786 (match_operand:DI 2 "register_operand" "r")))
3787 (clobber (reg:CC CC_REG))]
3790 "&& reload_completed"
3791 [(parallel [(set (reg:CC_NOOV CC_REG)
3792 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3794 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3796 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3797 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3798 "operands[3] = gen_lowpart (SImode, operands[2]);
3799 operands[4] = gen_highpart (SImode, operands[2]);
3800 operands[5] = gen_lowpart (SImode, operands[0]);
3801 operands[6] = gen_highpart (SImode, operands[0]);"
3802 [(set_attr "length" "2")])
3804 (define_insn "*adddi3_sp64"
3805 [(set (match_operand:DI 0 "register_operand" "=r,r")
3806 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3807 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3813 (define_insn "addsi3"
3814 [(set (match_operand:SI 0 "register_operand" "=r,r")
3815 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3816 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3821 [(set_attr "type" "*,*")
3822 (set_attr "fptype" "*,*")])
3824 (define_insn "*cmp_cc_plus"
3825 [(set (reg:CC_NOOV CC_REG)
3826 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3827 (match_operand:SI 1 "arith_operand" "rI"))
3830 "addcc\t%0, %1, %%g0"
3831 [(set_attr "type" "compare")])
3833 (define_insn "*cmp_ccx_plus"
3834 [(set (reg:CCX_NOOV CC_REG)
3835 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3836 (match_operand:DI 1 "arith_operand" "rI"))
3839 "addcc\t%0, %1, %%g0"
3840 [(set_attr "type" "compare")])
3842 (define_insn "*cmp_cc_plus_set"
3843 [(set (reg:CC_NOOV CC_REG)
3844 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3845 (match_operand:SI 2 "arith_operand" "rI"))
3847 (set (match_operand:SI 0 "register_operand" "=r")
3848 (plus:SI (match_dup 1) (match_dup 2)))]
3851 [(set_attr "type" "compare")])
3853 (define_insn "*cmp_ccx_plus_set"
3854 [(set (reg:CCX_NOOV CC_REG)
3855 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3856 (match_operand:DI 2 "arith_operand" "rI"))
3858 (set (match_operand:DI 0 "register_operand" "=r")
3859 (plus:DI (match_dup 1) (match_dup 2)))]
3862 [(set_attr "type" "compare")])
3864 (define_expand "subdi3"
3865 [(set (match_operand:DI 0 "register_operand" "")
3866 (minus:DI (match_operand:DI 1 "register_operand" "")
3867 (match_operand:DI 2 "arith_double_add_operand" "")))]
3870 if (! TARGET_ARCH64)
3872 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3873 gen_rtx_SET (VOIDmode, operands[0],
3874 gen_rtx_MINUS (DImode, operands[1],
3876 gen_rtx_CLOBBER (VOIDmode,
3877 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3882 (define_insn_and_split "*subdi3_insn_sp32"
3883 [(set (match_operand:DI 0 "register_operand" "=r")
3884 (minus:DI (match_operand:DI 1 "register_operand" "r")
3885 (match_operand:DI 2 "arith_double_operand" "rHI")))
3886 (clobber (reg:CC CC_REG))]
3889 "&& reload_completed"
3890 [(parallel [(set (reg:CC_NOOV CC_REG)
3891 (compare:CC_NOOV (minus:SI (match_dup 4)
3895 (minus:SI (match_dup 4) (match_dup 5)))])
3897 (minus:SI (minus:SI (match_dup 7)
3899 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3901 operands[3] = gen_lowpart (SImode, operands[0]);
3902 operands[4] = gen_lowpart (SImode, operands[1]);
3903 operands[5] = gen_lowpart (SImode, operands[2]);
3904 operands[6] = gen_highpart (SImode, operands[0]);
3905 operands[7] = gen_highpart (SImode, operands[1]);
3906 #if HOST_BITS_PER_WIDE_INT == 32
3907 if (GET_CODE (operands[2]) == CONST_INT)
3909 if (INTVAL (operands[2]) < 0)
3910 operands[8] = constm1_rtx;
3912 operands[8] = const0_rtx;
3916 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3918 [(set_attr "length" "2")])
3920 ;; LTU here means "carry set"
3922 [(set (match_operand:SI 0 "register_operand" "=r")
3923 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3924 (match_operand:SI 2 "arith_operand" "rI"))
3925 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3928 [(set_attr "type" "ialuX")])
3930 (define_insn "*subx_extend_sp64"
3931 [(set (match_operand:DI 0 "register_operand" "=r")
3932 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3933 (match_operand:SI 2 "arith_operand" "rI"))
3934 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3937 [(set_attr "type" "ialuX")])
3939 (define_insn_and_split "*subx_extend"
3940 [(set (match_operand:DI 0 "register_operand" "=r")
3941 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3942 (match_operand:SI 2 "arith_operand" "rI"))
3943 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3946 "&& reload_completed"
3947 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3948 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3949 (set (match_dup 4) (const_int 0))]
3950 "operands[3] = gen_lowpart (SImode, operands[0]);
3951 operands[4] = gen_highpart (SImode, operands[0]);"
3952 [(set_attr "length" "2")])
3954 (define_insn_and_split "*subdi3_extend_sp32"
3955 [(set (match_operand:DI 0 "register_operand" "=r")
3956 (minus:DI (match_operand:DI 1 "register_operand" "r")
3957 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3958 (clobber (reg:CC CC_REG))]
3961 "&& reload_completed"
3962 [(parallel [(set (reg:CC_NOOV CC_REG)
3963 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3965 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3967 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3968 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3969 "operands[3] = gen_lowpart (SImode, operands[1]);
3970 operands[4] = gen_highpart (SImode, operands[1]);
3971 operands[5] = gen_lowpart (SImode, operands[0]);
3972 operands[6] = gen_highpart (SImode, operands[0]);"
3973 [(set_attr "length" "2")])
3975 (define_insn "*subdi3_sp64"
3976 [(set (match_operand:DI 0 "register_operand" "=r,r")
3977 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3978 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3984 (define_insn "subsi3"
3985 [(set (match_operand:SI 0 "register_operand" "=r,r")
3986 (minus:SI (match_operand:SI 1 "register_operand" "r,r")
3987 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3992 [(set_attr "type" "*,*")
3993 (set_attr "fptype" "*,*")])
3995 (define_insn "*cmp_minus_cc"
3996 [(set (reg:CC_NOOV CC_REG)
3997 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3998 (match_operand:SI 1 "arith_operand" "rI"))
4001 "subcc\t%r0, %1, %%g0"
4002 [(set_attr "type" "compare")])
4004 (define_insn "*cmp_minus_ccx"
4005 [(set (reg:CCX_NOOV CC_REG)
4006 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4007 (match_operand:DI 1 "arith_operand" "rI"))
4010 "subcc\t%0, %1, %%g0"
4011 [(set_attr "type" "compare")])
4013 (define_insn "cmp_minus_cc_set"
4014 [(set (reg:CC_NOOV CC_REG)
4015 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4016 (match_operand:SI 2 "arith_operand" "rI"))
4018 (set (match_operand:SI 0 "register_operand" "=r")
4019 (minus:SI (match_dup 1) (match_dup 2)))]
4021 "subcc\t%r1, %2, %0"
4022 [(set_attr "type" "compare")])
4024 (define_insn "*cmp_minus_ccx_set"
4025 [(set (reg:CCX_NOOV CC_REG)
4026 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4027 (match_operand:DI 2 "arith_operand" "rI"))
4029 (set (match_operand:DI 0 "register_operand" "=r")
4030 (minus:DI (match_dup 1) (match_dup 2)))]
4033 [(set_attr "type" "compare")])
4036 ;; Integer multiply/divide instructions.
4038 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4039 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4041 (define_insn "mulsi3"
4042 [(set (match_operand:SI 0 "register_operand" "=r")
4043 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4044 (match_operand:SI 2 "arith_operand" "rI")))]
4047 [(set_attr "type" "imul")])
4049 (define_expand "muldi3"
4050 [(set (match_operand:DI 0 "register_operand" "")
4051 (mult:DI (match_operand:DI 1 "arith_operand" "")
4052 (match_operand:DI 2 "arith_operand" "")))]
4053 "TARGET_ARCH64 || TARGET_V8PLUS"
4057 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4062 (define_insn "*muldi3_sp64"
4063 [(set (match_operand:DI 0 "register_operand" "=r")
4064 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4065 (match_operand:DI 2 "arith_operand" "rI")))]
4068 [(set_attr "type" "imul")])
4070 ;; V8plus wide multiply.
4072 (define_insn "muldi3_v8plus"
4073 [(set (match_operand:DI 0 "register_operand" "=r,h")
4074 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4075 (match_operand:DI 2 "arith_operand" "rI,rI")))
4076 (clobber (match_scratch:SI 3 "=&h,X"))
4077 (clobber (match_scratch:SI 4 "=&h,X"))]
4079 "* return output_v8plus_mult (insn, operands, \"mulx\");"
4080 [(set_attr "type" "multi")
4081 (set_attr "length" "9,8")])
4083 (define_insn "*cmp_mul_set"
4084 [(set (reg:CC CC_REG)
4085 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4086 (match_operand:SI 2 "arith_operand" "rI"))
4088 (set (match_operand:SI 0 "register_operand" "=r")
4089 (mult:SI (match_dup 1) (match_dup 2)))]
4090 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4091 "smulcc\t%1, %2, %0"
4092 [(set_attr "type" "imul")])
4094 (define_expand "mulsidi3"
4095 [(set (match_operand:DI 0 "register_operand" "")
4096 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4097 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4100 if (CONSTANT_P (operands[2]))
4103 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4105 else if (TARGET_ARCH32)
4106 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4109 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4115 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4120 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4121 ;; registers can hold 64-bit values in the V8plus environment.
4123 (define_insn "mulsidi3_v8plus"
4124 [(set (match_operand:DI 0 "register_operand" "=h,r")
4125 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4126 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4127 (clobber (match_scratch:SI 3 "=X,&h"))]
4130 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4131 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4132 [(set_attr "type" "multi")
4133 (set_attr "length" "2,3")])
4136 (define_insn "const_mulsidi3_v8plus"
4137 [(set (match_operand:DI 0 "register_operand" "=h,r")
4138 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4139 (match_operand:DI 2 "small_int_operand" "I,I")))
4140 (clobber (match_scratch:SI 3 "=X,&h"))]
4143 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4144 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4145 [(set_attr "type" "multi")
4146 (set_attr "length" "2,3")])
4149 (define_insn "*mulsidi3_sp32"
4150 [(set (match_operand:DI 0 "register_operand" "=r")
4151 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4152 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4155 return TARGET_SPARCLET
4156 ? "smuld\t%1, %2, %L0"
4157 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4160 (if_then_else (eq_attr "isa" "sparclet")
4161 (const_string "imul") (const_string "multi")))
4162 (set (attr "length")
4163 (if_then_else (eq_attr "isa" "sparclet")
4164 (const_int 1) (const_int 2)))])
4166 (define_insn "*mulsidi3_sp64"
4167 [(set (match_operand:DI 0 "register_operand" "=r")
4168 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4169 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4170 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4172 [(set_attr "type" "imul")])
4174 ;; Extra pattern, because sign_extend of a constant isn't valid.
4177 (define_insn "const_mulsidi3_sp32"
4178 [(set (match_operand:DI 0 "register_operand" "=r")
4179 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4180 (match_operand:DI 2 "small_int_operand" "I")))]
4183 return TARGET_SPARCLET
4184 ? "smuld\t%1, %2, %L0"
4185 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4188 (if_then_else (eq_attr "isa" "sparclet")
4189 (const_string "imul") (const_string "multi")))
4190 (set (attr "length")
4191 (if_then_else (eq_attr "isa" "sparclet")
4192 (const_int 1) (const_int 2)))])
4194 (define_insn "const_mulsidi3_sp64"
4195 [(set (match_operand:DI 0 "register_operand" "=r")
4196 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4197 (match_operand:DI 2 "small_int_operand" "I")))]
4198 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4200 [(set_attr "type" "imul")])
4202 (define_expand "smulsi3_highpart"
4203 [(set (match_operand:SI 0 "register_operand" "")
4205 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4206 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4208 "TARGET_HARD_MUL && TARGET_ARCH32"
4210 if (CONSTANT_P (operands[2]))
4214 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4220 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4225 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4226 operands[2], GEN_INT (32)));
4232 (define_insn "smulsi3_highpart_v8plus"
4233 [(set (match_operand:SI 0 "register_operand" "=h,r")
4235 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4236 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4237 (match_operand:SI 3 "small_int_operand" "I,I"))))
4238 (clobber (match_scratch:SI 4 "=X,&h"))]
4241 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4242 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4243 [(set_attr "type" "multi")
4244 (set_attr "length" "2")])
4246 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4249 [(set (match_operand:SI 0 "register_operand" "=h,r")
4252 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4253 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4254 (match_operand:SI 3 "small_int_operand" "I,I"))
4256 (clobber (match_scratch:SI 4 "=X,&h"))]
4259 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4260 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4261 [(set_attr "type" "multi")
4262 (set_attr "length" "2")])
4265 (define_insn "const_smulsi3_highpart_v8plus"
4266 [(set (match_operand:SI 0 "register_operand" "=h,r")
4268 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4269 (match_operand:DI 2 "small_int_operand" "I,I"))
4270 (match_operand:SI 3 "small_int_operand" "I,I"))))
4271 (clobber (match_scratch:SI 4 "=X,&h"))]
4274 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4275 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4276 [(set_attr "type" "multi")
4277 (set_attr "length" "2")])
4280 (define_insn "*smulsi3_highpart_sp32"
4281 [(set (match_operand:SI 0 "register_operand" "=r")
4283 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4284 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4287 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4288 [(set_attr "type" "multi")
4289 (set_attr "length" "2")])
4292 (define_insn "const_smulsi3_highpart"
4293 [(set (match_operand:SI 0 "register_operand" "=r")
4295 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4296 (match_operand:DI 2 "small_int_operand" "i"))
4299 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4300 [(set_attr "type" "multi")
4301 (set_attr "length" "2")])
4303 (define_expand "umulsidi3"
4304 [(set (match_operand:DI 0 "register_operand" "")
4305 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4306 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4309 if (CONSTANT_P (operands[2]))
4312 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4314 else if (TARGET_ARCH32)
4315 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4318 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4324 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4330 (define_insn "umulsidi3_v8plus"
4331 [(set (match_operand:DI 0 "register_operand" "=h,r")
4332 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4333 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4334 (clobber (match_scratch:SI 3 "=X,&h"))]
4337 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4338 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4339 [(set_attr "type" "multi")
4340 (set_attr "length" "2,3")])
4343 (define_insn "*umulsidi3_sp32"
4344 [(set (match_operand:DI 0 "register_operand" "=r")
4345 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4346 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4349 return TARGET_SPARCLET
4350 ? "umuld\t%1, %2, %L0"
4351 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4354 (if_then_else (eq_attr "isa" "sparclet")
4355 (const_string "imul") (const_string "multi")))
4356 (set (attr "length")
4357 (if_then_else (eq_attr "isa" "sparclet")
4358 (const_int 1) (const_int 2)))])
4360 (define_insn "*umulsidi3_sp64"
4361 [(set (match_operand:DI 0 "register_operand" "=r")
4362 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4363 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4364 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4366 [(set_attr "type" "imul")])
4368 ;; Extra pattern, because sign_extend of a constant isn't valid.
4371 (define_insn "const_umulsidi3_sp32"
4372 [(set (match_operand:DI 0 "register_operand" "=r")
4373 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4374 (match_operand:DI 2 "uns_small_int_operand" "")))]
4377 return TARGET_SPARCLET
4378 ? "umuld\t%1, %s2, %L0"
4379 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4382 (if_then_else (eq_attr "isa" "sparclet")
4383 (const_string "imul") (const_string "multi")))
4384 (set (attr "length")
4385 (if_then_else (eq_attr "isa" "sparclet")
4386 (const_int 1) (const_int 2)))])
4388 (define_insn "const_umulsidi3_sp64"
4389 [(set (match_operand:DI 0 "register_operand" "=r")
4390 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4391 (match_operand:DI 2 "uns_small_int_operand" "")))]
4392 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4394 [(set_attr "type" "imul")])
4397 (define_insn "const_umulsidi3_v8plus"
4398 [(set (match_operand:DI 0 "register_operand" "=h,r")
4399 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4400 (match_operand:DI 2 "uns_small_int_operand" "")))
4401 (clobber (match_scratch:SI 3 "=X,h"))]
4404 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4405 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4406 [(set_attr "type" "multi")
4407 (set_attr "length" "2,3")])
4409 (define_expand "umulsi3_highpart"
4410 [(set (match_operand:SI 0 "register_operand" "")
4412 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4413 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4415 "TARGET_HARD_MUL && TARGET_ARCH32"
4417 if (CONSTANT_P (operands[2]))
4421 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4427 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4432 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4433 operands[2], GEN_INT (32)));
4439 (define_insn "umulsi3_highpart_v8plus"
4440 [(set (match_operand:SI 0 "register_operand" "=h,r")
4442 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4443 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4444 (match_operand:SI 3 "small_int_operand" "I,I"))))
4445 (clobber (match_scratch:SI 4 "=X,h"))]
4448 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4449 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4450 [(set_attr "type" "multi")
4451 (set_attr "length" "2")])
4454 (define_insn "const_umulsi3_highpart_v8plus"
4455 [(set (match_operand:SI 0 "register_operand" "=h,r")
4457 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4458 (match_operand:DI 2 "uns_small_int_operand" ""))
4459 (match_operand:SI 3 "small_int_operand" "I,I"))))
4460 (clobber (match_scratch:SI 4 "=X,h"))]
4463 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4464 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4465 [(set_attr "type" "multi")
4466 (set_attr "length" "2")])
4469 (define_insn "*umulsi3_highpart_sp32"
4470 [(set (match_operand:SI 0 "register_operand" "=r")
4472 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4473 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4476 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4477 [(set_attr "type" "multi")
4478 (set_attr "length" "2")])
4481 (define_insn "const_umulsi3_highpart"
4482 [(set (match_operand:SI 0 "register_operand" "=r")
4484 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4485 (match_operand:DI 2 "uns_small_int_operand" ""))
4488 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4489 [(set_attr "type" "multi")
4490 (set_attr "length" "2")])
4492 (define_expand "divsi3"
4493 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4494 (div:SI (match_operand:SI 1 "register_operand" "")
4495 (match_operand:SI 2 "input_operand" "")))
4496 (clobber (match_scratch:SI 3 ""))])]
4497 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4501 operands[3] = gen_reg_rtx(SImode);
4502 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4503 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4509 ;; The V8 architecture specifies that there must be at least 3 instructions
4510 ;; between a write to the Y register and a use of it for correct results.
4511 ;; We try to fill one of them with a simple constant or a memory load.
4513 (define_insn "divsi3_sp32"
4514 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4515 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4516 (match_operand:SI 2 "input_operand" "rI,K,m")))
4517 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4518 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4520 output_asm_insn ("sra\t%1, 31, %3", operands);
4521 output_asm_insn ("wr\t%3, 0, %%y", operands);
4523 switch (which_alternative)
4527 return "sdiv\t%1, %2, %0";
4529 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4532 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4534 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4537 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4539 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4544 [(set_attr "type" "multi")
4545 (set (attr "length")
4546 (if_then_else (eq_attr "isa" "v9")
4547 (const_int 4) (const_int 6)))])
4549 (define_insn "divsi3_sp64"
4550 [(set (match_operand:SI 0 "register_operand" "=r")
4551 (div:SI (match_operand:SI 1 "register_operand" "r")
4552 (match_operand:SI 2 "input_operand" "rI")))
4553 (use (match_operand:SI 3 "register_operand" "r"))]
4554 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4555 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4556 [(set_attr "type" "multi")
4557 (set_attr "length" "2")])
4559 (define_insn "divdi3"
4560 [(set (match_operand:DI 0 "register_operand" "=r")
4561 (div:DI (match_operand:DI 1 "register_operand" "r")
4562 (match_operand:DI 2 "arith_operand" "rI")))]
4565 [(set_attr "type" "idiv")])
4567 (define_insn "*cmp_sdiv_cc_set"
4568 [(set (reg:CC CC_REG)
4569 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4570 (match_operand:SI 2 "arith_operand" "rI"))
4572 (set (match_operand:SI 0 "register_operand" "=r")
4573 (div:SI (match_dup 1) (match_dup 2)))
4574 (clobber (match_scratch:SI 3 "=&r"))]
4575 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4577 output_asm_insn ("sra\t%1, 31, %3", operands);
4578 output_asm_insn ("wr\t%3, 0, %%y", operands);
4581 return "sdivcc\t%1, %2, %0";
4583 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4585 [(set_attr "type" "multi")
4586 (set (attr "length")
4587 (if_then_else (eq_attr "isa" "v9")
4588 (const_int 3) (const_int 6)))])
4591 (define_expand "udivsi3"
4592 [(set (match_operand:SI 0 "register_operand" "")
4593 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4594 (match_operand:SI 2 "input_operand" "")))]
4595 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4598 ;; The V8 architecture specifies that there must be at least 3 instructions
4599 ;; between a write to the Y register and a use of it for correct results.
4600 ;; We try to fill one of them with a simple constant or a memory load.
4602 (define_insn "udivsi3_sp32"
4603 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4604 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4605 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4606 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4608 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4610 switch (which_alternative)
4614 return "udiv\t%1, %2, %0";
4616 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4619 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4621 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4624 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4626 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4629 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4631 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4636 [(set_attr "type" "multi")
4637 (set (attr "length")
4638 (if_then_else (eq_attr "isa" "v9")
4639 (const_int 3) (const_int 5)))])
4641 (define_insn "udivsi3_sp64"
4642 [(set (match_operand:SI 0 "register_operand" "=r")
4643 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4644 (match_operand:SI 2 "input_operand" "rI")))]
4645 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4646 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4647 [(set_attr "type" "multi")
4648 (set_attr "length" "2")])
4650 (define_insn "udivdi3"
4651 [(set (match_operand:DI 0 "register_operand" "=r")
4652 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4653 (match_operand:DI 2 "arith_operand" "rI")))]
4656 [(set_attr "type" "idiv")])
4658 (define_insn "*cmp_udiv_cc_set"
4659 [(set (reg:CC CC_REG)
4660 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4661 (match_operand:SI 2 "arith_operand" "rI"))
4663 (set (match_operand:SI 0 "register_operand" "=r")
4664 (udiv:SI (match_dup 1) (match_dup 2)))]
4665 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4667 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4670 return "udivcc\t%1, %2, %0";
4672 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4674 [(set_attr "type" "multi")
4675 (set (attr "length")
4676 (if_then_else (eq_attr "isa" "v9")
4677 (const_int 2) (const_int 5)))])
4679 ; sparclet multiply/accumulate insns
4681 (define_insn "*smacsi"
4682 [(set (match_operand:SI 0 "register_operand" "=r")
4683 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4684 (match_operand:SI 2 "arith_operand" "rI"))
4685 (match_operand:SI 3 "register_operand" "0")))]
4688 [(set_attr "type" "imul")])
4690 (define_insn "*smacdi"
4691 [(set (match_operand:DI 0 "register_operand" "=r")
4692 (plus:DI (mult:DI (sign_extend:DI
4693 (match_operand:SI 1 "register_operand" "%r"))
4695 (match_operand:SI 2 "register_operand" "r")))
4696 (match_operand:DI 3 "register_operand" "0")))]
4698 "smacd\t%1, %2, %L0"
4699 [(set_attr "type" "imul")])
4701 (define_insn "*umacdi"
4702 [(set (match_operand:DI 0 "register_operand" "=r")
4703 (plus:DI (mult:DI (zero_extend:DI
4704 (match_operand:SI 1 "register_operand" "%r"))
4706 (match_operand:SI 2 "register_operand" "r")))
4707 (match_operand:DI 3 "register_operand" "0")))]
4709 "umacd\t%1, %2, %L0"
4710 [(set_attr "type" "imul")])
4713 ;; Boolean instructions.
4715 ;; We define DImode `and' so with DImode `not' we can get
4716 ;; DImode `andn'. Other combinations are possible.
4718 (define_expand "anddi3"
4719 [(set (match_operand:DI 0 "register_operand" "")
4720 (and:DI (match_operand:DI 1 "arith_double_operand" "")
4721 (match_operand:DI 2 "arith_double_operand" "")))]
4725 (define_insn "*anddi3_sp32"
4726 [(set (match_operand:DI 0 "register_operand" "=r")
4727 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4728 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4732 (define_insn "*anddi3_sp64"
4733 [(set (match_operand:DI 0 "register_operand" "=r")
4734 (and:DI (match_operand:DI 1 "arith_operand" "%r")
4735 (match_operand:DI 2 "arith_operand" "rI")))]
4739 (define_insn "andsi3"
4740 [(set (match_operand:SI 0 "register_operand" "=r")
4741 (and:SI (match_operand:SI 1 "arith_operand" "%r")
4742 (match_operand:SI 2 "arith_operand" "rI")))]
4747 [(set (match_operand:SI 0 "register_operand" "")
4748 (and:SI (match_operand:SI 1 "register_operand" "")
4749 (match_operand:SI 2 "const_compl_high_operand" "")))
4750 (clobber (match_operand:SI 3 "register_operand" ""))]
4752 [(set (match_dup 3) (match_dup 4))
4753 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4755 operands[4] = GEN_INT (~INTVAL (operands[2]));
4758 (define_insn_and_split "*and_not_di_sp32"
4759 [(set (match_operand:DI 0 "register_operand" "=r")
4760 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4761 (match_operand:DI 2 "register_operand" "r")))]
4764 "&& reload_completed
4765 && ((GET_CODE (operands[0]) == REG
4766 && SPARC_INT_REG_P (REGNO (operands[0])))
4767 || (GET_CODE (operands[0]) == SUBREG
4768 && GET_CODE (SUBREG_REG (operands[0])) == REG
4769 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4770 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4771 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4772 "operands[3] = gen_highpart (SImode, operands[0]);
4773 operands[4] = gen_highpart (SImode, operands[1]);
4774 operands[5] = gen_highpart (SImode, operands[2]);
4775 operands[6] = gen_lowpart (SImode, operands[0]);
4776 operands[7] = gen_lowpart (SImode, operands[1]);
4777 operands[8] = gen_lowpart (SImode, operands[2]);"
4778 [(set_attr "length" "2")])
4780 (define_insn "*and_not_di_sp64"
4781 [(set (match_operand:DI 0 "register_operand" "=r")
4782 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4783 (match_operand:DI 2 "register_operand" "r")))]
4787 (define_insn "*and_not_si"
4788 [(set (match_operand:SI 0 "register_operand" "=r")
4789 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4790 (match_operand:SI 2 "register_operand" "r")))]
4794 (define_expand "iordi3"
4795 [(set (match_operand:DI 0 "register_operand" "")
4796 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4797 (match_operand:DI 2 "arith_double_operand" "")))]
4801 (define_insn "*iordi3_sp32"
4802 [(set (match_operand:DI 0 "register_operand" "=r")
4803 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4804 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4807 [(set_attr "length" "2")])
4809 (define_insn "*iordi3_sp64"
4810 [(set (match_operand:DI 0 "register_operand" "=r")
4811 (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4812 (match_operand:DI 2 "arith_operand" "rI")))]
4816 (define_insn "iorsi3"
4817 [(set (match_operand:SI 0 "register_operand" "=r")
4818 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4819 (match_operand:SI 2 "arith_operand" "rI")))]
4824 [(set (match_operand:SI 0 "register_operand" "")
4825 (ior:SI (match_operand:SI 1 "register_operand" "")
4826 (match_operand:SI 2 "const_compl_high_operand" "")))
4827 (clobber (match_operand:SI 3 "register_operand" ""))]
4829 [(set (match_dup 3) (match_dup 4))
4830 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4832 operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4835 (define_insn_and_split "*or_not_di_sp32"
4836 [(set (match_operand:DI 0 "register_operand" "=r")
4837 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4838 (match_operand:DI 2 "register_operand" "r")))]
4841 "&& reload_completed
4842 && ((GET_CODE (operands[0]) == REG
4843 && SPARC_INT_REG_P (REGNO (operands[0])))
4844 || (GET_CODE (operands[0]) == SUBREG
4845 && GET_CODE (SUBREG_REG (operands[0])) == REG
4846 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4847 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4848 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4849 "operands[3] = gen_highpart (SImode, operands[0]);
4850 operands[4] = gen_highpart (SImode, operands[1]);
4851 operands[5] = gen_highpart (SImode, operands[2]);
4852 operands[6] = gen_lowpart (SImode, operands[0]);
4853 operands[7] = gen_lowpart (SImode, operands[1]);
4854 operands[8] = gen_lowpart (SImode, operands[2]);"
4855 [(set_attr "length" "2")])
4857 (define_insn "*or_not_di_sp64"
4858 [(set (match_operand:DI 0 "register_operand" "=r")
4859 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4860 (match_operand:DI 2 "register_operand" "r")))]
4864 (define_insn "*or_not_si"
4865 [(set (match_operand:SI 0 "register_operand" "=r")
4866 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4867 (match_operand:SI 2 "register_operand" "r")))]
4871 (define_expand "xordi3"
4872 [(set (match_operand:DI 0 "register_operand" "")
4873 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4874 (match_operand:DI 2 "arith_double_operand" "")))]
4878 (define_insn "*xordi3_sp32"
4879 [(set (match_operand:DI 0 "register_operand" "=r")
4880 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4881 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4884 [(set_attr "length" "2")])
4886 (define_insn "*xordi3_sp64"
4887 [(set (match_operand:DI 0 "register_operand" "=r")
4888 (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4889 (match_operand:DI 2 "arith_operand" "rI")))]
4893 (define_insn "xorsi3"
4894 [(set (match_operand:SI 0 "register_operand" "=r")
4895 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4896 (match_operand:SI 2 "arith_operand" "rI")))]
4901 [(set (match_operand:SI 0 "register_operand" "")
4902 (xor:SI (match_operand:SI 1 "register_operand" "")
4903 (match_operand:SI 2 "const_compl_high_operand" "")))
4904 (clobber (match_operand:SI 3 "register_operand" ""))]
4906 [(set (match_dup 3) (match_dup 4))
4907 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4909 operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4913 [(set (match_operand:SI 0 "register_operand" "")
4914 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4915 (match_operand:SI 2 "const_compl_high_operand" ""))))
4916 (clobber (match_operand:SI 3 "register_operand" ""))]
4918 [(set (match_dup 3) (match_dup 4))
4919 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4921 operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4924 ;; Split DImode logical operations requiring two instructions.
4926 [(set (match_operand:DI 0 "register_operand" "")
4927 (match_operator:DI 1 "cc_arith_operator" ; AND, IOR, XOR
4928 [(match_operand:DI 2 "register_operand" "")
4929 (match_operand:DI 3 "arith_double_operand" "")]))]
4932 && ((GET_CODE (operands[0]) == REG
4933 && SPARC_INT_REG_P (REGNO (operands[0])))
4934 || (GET_CODE (operands[0]) == SUBREG
4935 && GET_CODE (SUBREG_REG (operands[0])) == REG
4936 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4937 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4938 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4940 operands[4] = gen_highpart (SImode, operands[0]);
4941 operands[5] = gen_lowpart (SImode, operands[0]);
4942 operands[6] = gen_highpart (SImode, operands[2]);
4943 operands[7] = gen_lowpart (SImode, operands[2]);
4944 #if HOST_BITS_PER_WIDE_INT == 32
4945 if (GET_CODE (operands[3]) == CONST_INT)
4947 if (INTVAL (operands[3]) < 0)
4948 operands[8] = constm1_rtx;
4950 operands[8] = const0_rtx;
4954 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
4955 operands[9] = gen_lowpart (SImode, operands[3]);
4958 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4959 ;; Combine now canonicalizes to the rightmost expression.
4960 (define_insn_and_split "*xor_not_di_sp32"
4961 [(set (match_operand:DI 0 "register_operand" "=r")
4962 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
4963 (match_operand:DI 2 "register_operand" "r"))))]
4966 "&& reload_completed
4967 && ((GET_CODE (operands[0]) == REG
4968 && SPARC_INT_REG_P (REGNO (operands[0])))
4969 || (GET_CODE (operands[0]) == SUBREG
4970 && GET_CODE (SUBREG_REG (operands[0])) == REG
4971 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4972 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4973 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4974 "operands[3] = gen_highpart (SImode, operands[0]);
4975 operands[4] = gen_highpart (SImode, operands[1]);
4976 operands[5] = gen_highpart (SImode, operands[2]);
4977 operands[6] = gen_lowpart (SImode, operands[0]);
4978 operands[7] = gen_lowpart (SImode, operands[1]);
4979 operands[8] = gen_lowpart (SImode, operands[2]);"
4980 [(set_attr "length" "2")])
4982 (define_insn "*xor_not_di_sp64"
4983 [(set (match_operand:DI 0 "register_operand" "=r")
4984 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4985 (match_operand:DI 2 "arith_operand" "rI"))))]
4987 "xnor\t%r1, %2, %0")
4989 (define_insn "*xor_not_si"
4990 [(set (match_operand:SI 0 "register_operand" "=r")
4991 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4992 (match_operand:SI 2 "arith_operand" "rI"))))]
4994 "xnor\t%r1, %2, %0")
4996 ;; These correspond to the above in the case where we also (or only)
4997 ;; want to set the condition code.
4999 (define_insn "*cmp_cc_arith_op"
5000 [(set (reg:CC CC_REG)
5002 (match_operator:SI 2 "cc_arith_operator"
5003 [(match_operand:SI 0 "arith_operand" "%r")
5004 (match_operand:SI 1 "arith_operand" "rI")])
5007 "%A2cc\t%0, %1, %%g0"
5008 [(set_attr "type" "compare")])
5010 (define_insn "*cmp_ccx_arith_op"
5011 [(set (reg:CCX CC_REG)
5013 (match_operator:DI 2 "cc_arith_operator"
5014 [(match_operand:DI 0 "arith_operand" "%r")
5015 (match_operand:DI 1 "arith_operand" "rI")])
5018 "%A2cc\t%0, %1, %%g0"
5019 [(set_attr "type" "compare")])
5021 (define_insn "*cmp_cc_arith_op_set"
5022 [(set (reg:CC CC_REG)
5024 (match_operator:SI 3 "cc_arith_operator"
5025 [(match_operand:SI 1 "arith_operand" "%r")
5026 (match_operand:SI 2 "arith_operand" "rI")])
5028 (set (match_operand:SI 0 "register_operand" "=r")
5029 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5030 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5032 [(set_attr "type" "compare")])
5034 (define_insn "*cmp_ccx_arith_op_set"
5035 [(set (reg:CCX CC_REG)
5037 (match_operator:DI 3 "cc_arith_operator"
5038 [(match_operand:DI 1 "arith_operand" "%r")
5039 (match_operand:DI 2 "arith_operand" "rI")])
5041 (set (match_operand:DI 0 "register_operand" "=r")
5042 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5043 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5045 [(set_attr "type" "compare")])
5047 (define_insn "*cmp_cc_xor_not"
5048 [(set (reg:CC CC_REG)
5050 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5051 (match_operand:SI 1 "arith_operand" "rI")))
5054 "xnorcc\t%r0, %1, %%g0"
5055 [(set_attr "type" "compare")])
5057 (define_insn "*cmp_ccx_xor_not"
5058 [(set (reg:CCX CC_REG)
5060 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5061 (match_operand:DI 1 "arith_operand" "rI")))
5064 "xnorcc\t%r0, %1, %%g0"
5065 [(set_attr "type" "compare")])
5067 (define_insn "*cmp_cc_xor_not_set"
5068 [(set (reg:CC CC_REG)
5070 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5071 (match_operand:SI 2 "arith_operand" "rI")))
5073 (set (match_operand:SI 0 "register_operand" "=r")
5074 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5076 "xnorcc\t%r1, %2, %0"
5077 [(set_attr "type" "compare")])
5079 (define_insn "*cmp_ccx_xor_not_set"
5080 [(set (reg:CCX CC_REG)
5082 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5083 (match_operand:DI 2 "arith_operand" "rI")))
5085 (set (match_operand:DI 0 "register_operand" "=r")
5086 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5088 "xnorcc\t%r1, %2, %0"
5089 [(set_attr "type" "compare")])
5091 (define_insn "*cmp_cc_arith_op_not"
5092 [(set (reg:CC CC_REG)
5094 (match_operator:SI 2 "cc_arith_not_operator"
5095 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5096 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5099 "%B2cc\t%r1, %0, %%g0"
5100 [(set_attr "type" "compare")])
5102 (define_insn "*cmp_ccx_arith_op_not"
5103 [(set (reg:CCX CC_REG)
5105 (match_operator:DI 2 "cc_arith_not_operator"
5106 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5107 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5110 "%B2cc\t%r1, %0, %%g0"
5111 [(set_attr "type" "compare")])
5113 (define_insn "*cmp_cc_arith_op_not_set"
5114 [(set (reg:CC CC_REG)
5116 (match_operator:SI 3 "cc_arith_not_operator"
5117 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5118 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5120 (set (match_operand:SI 0 "register_operand" "=r")
5121 (match_operator:SI 4 "cc_arith_not_operator"
5122 [(not:SI (match_dup 1)) (match_dup 2)]))]
5123 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5124 "%B3cc\t%r2, %1, %0"
5125 [(set_attr "type" "compare")])
5127 (define_insn "*cmp_ccx_arith_op_not_set"
5128 [(set (reg:CCX CC_REG)
5130 (match_operator:DI 3 "cc_arith_not_operator"
5131 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5132 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5134 (set (match_operand:DI 0 "register_operand" "=r")
5135 (match_operator:DI 4 "cc_arith_not_operator"
5136 [(not:DI (match_dup 1)) (match_dup 2)]))]
5137 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5138 "%B3cc\t%r2, %1, %0"
5139 [(set_attr "type" "compare")])
5141 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5142 ;; does not know how to make it work for constants.
5144 (define_expand "negdi2"
5145 [(set (match_operand:DI 0 "register_operand" "=r")
5146 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5149 if (! TARGET_ARCH64)
5151 emit_insn (gen_rtx_PARALLEL
5154 gen_rtx_SET (VOIDmode, operand0,
5155 gen_rtx_NEG (DImode, operand1)),
5156 gen_rtx_CLOBBER (VOIDmode,
5157 gen_rtx_REG (CCmode,
5163 (define_insn_and_split "*negdi2_sp32"
5164 [(set (match_operand:DI 0 "register_operand" "=r")
5165 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5166 (clobber (reg:CC CC_REG))]
5169 "&& reload_completed"
5170 [(parallel [(set (reg:CC_NOOV CC_REG)
5171 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5173 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5174 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5175 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5176 "operands[2] = gen_highpart (SImode, operands[0]);
5177 operands[3] = gen_highpart (SImode, operands[1]);
5178 operands[4] = gen_lowpart (SImode, operands[0]);
5179 operands[5] = gen_lowpart (SImode, operands[1]);"
5180 [(set_attr "length" "2")])
5182 (define_insn "*negdi2_sp64"
5183 [(set (match_operand:DI 0 "register_operand" "=r")
5184 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5186 "sub\t%%g0, %1, %0")
5188 (define_insn "negsi2"
5189 [(set (match_operand:SI 0 "register_operand" "=r")
5190 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5192 "sub\t%%g0, %1, %0")
5194 (define_insn "*cmp_cc_neg"
5195 [(set (reg:CC_NOOV CC_REG)
5196 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5199 "subcc\t%%g0, %0, %%g0"
5200 [(set_attr "type" "compare")])
5202 (define_insn "*cmp_ccx_neg"
5203 [(set (reg:CCX_NOOV CC_REG)
5204 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5207 "subcc\t%%g0, %0, %%g0"
5208 [(set_attr "type" "compare")])
5210 (define_insn "*cmp_cc_set_neg"
5211 [(set (reg:CC_NOOV CC_REG)
5212 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5214 (set (match_operand:SI 0 "register_operand" "=r")
5215 (neg:SI (match_dup 1)))]
5217 "subcc\t%%g0, %1, %0"
5218 [(set_attr "type" "compare")])
5220 (define_insn "*cmp_ccx_set_neg"
5221 [(set (reg:CCX_NOOV CC_REG)
5222 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5224 (set (match_operand:DI 0 "register_operand" "=r")
5225 (neg:DI (match_dup 1)))]
5227 "subcc\t%%g0, %1, %0"
5228 [(set_attr "type" "compare")])
5230 ;; We cannot use the "not" pseudo insn because the Sun assembler
5231 ;; does not know how to make it work for constants.
5232 (define_expand "one_cmpldi2"
5233 [(set (match_operand:DI 0 "register_operand" "")
5234 (not:DI (match_operand:DI 1 "register_operand" "")))]
5238 (define_insn_and_split "*one_cmpldi2_sp32"
5239 [(set (match_operand:DI 0 "register_operand" "=r")
5240 (not:DI (match_operand:DI 1 "register_operand" "r")))]
5243 "&& reload_completed
5244 && ((GET_CODE (operands[0]) == REG
5245 && SPARC_INT_REG_P (REGNO (operands[0])))
5246 || (GET_CODE (operands[0]) == SUBREG
5247 && GET_CODE (SUBREG_REG (operands[0])) == REG
5248 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
5249 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5250 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5251 "operands[2] = gen_highpart (SImode, operands[0]);
5252 operands[3] = gen_highpart (SImode, operands[1]);
5253 operands[4] = gen_lowpart (SImode, operands[0]);
5254 operands[5] = gen_lowpart (SImode, operands[1]);"
5255 [(set_attr "length" "2")])
5257 (define_insn "*one_cmpldi2_sp64"
5258 [(set (match_operand:DI 0 "register_operand" "=r")
5259 (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5261 "xnor\t%%g0, %1, %0")
5263 (define_insn "one_cmplsi2"
5264 [(set (match_operand:SI 0 "register_operand" "=r")
5265 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5267 "xnor\t%%g0, %1, %0")
5269 (define_insn "*cmp_cc_not"
5270 [(set (reg:CC CC_REG)
5271 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5274 "xnorcc\t%%g0, %0, %%g0"
5275 [(set_attr "type" "compare")])
5277 (define_insn "*cmp_ccx_not"
5278 [(set (reg:CCX CC_REG)
5279 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5282 "xnorcc\t%%g0, %0, %%g0"
5283 [(set_attr "type" "compare")])
5285 (define_insn "*cmp_cc_set_not"
5286 [(set (reg:CC CC_REG)
5287 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5289 (set (match_operand:SI 0 "register_operand" "=r")
5290 (not:SI (match_dup 1)))]
5292 "xnorcc\t%%g0, %1, %0"
5293 [(set_attr "type" "compare")])
5295 (define_insn "*cmp_ccx_set_not"
5296 [(set (reg:CCX CC_REG)
5297 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5299 (set (match_operand:DI 0 "register_operand" "=r")
5300 (not:DI (match_dup 1)))]
5302 "xnorcc\t%%g0, %1, %0"
5303 [(set_attr "type" "compare")])
5305 (define_insn "*cmp_cc_set"
5306 [(set (match_operand:SI 0 "register_operand" "=r")
5307 (match_operand:SI 1 "register_operand" "r"))
5308 (set (reg:CC CC_REG)
5309 (compare:CC (match_dup 1)
5313 [(set_attr "type" "compare")])
5315 (define_insn "*cmp_ccx_set64"
5316 [(set (match_operand:DI 0 "register_operand" "=r")
5317 (match_operand:DI 1 "register_operand" "r"))
5318 (set (reg:CCX CC_REG)
5319 (compare:CCX (match_dup 1)
5323 [(set_attr "type" "compare")])
5326 ;; Floating point arithmetic instructions.
5328 (define_expand "addtf3"
5329 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5330 (plus:TF (match_operand:TF 1 "general_operand" "")
5331 (match_operand:TF 2 "general_operand" "")))]
5332 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5333 "emit_tfmode_binop (PLUS, operands); DONE;")
5335 (define_insn "*addtf3_hq"
5336 [(set (match_operand:TF 0 "register_operand" "=e")
5337 (plus:TF (match_operand:TF 1 "register_operand" "e")
5338 (match_operand:TF 2 "register_operand" "e")))]
5339 "TARGET_FPU && TARGET_HARD_QUAD"
5341 [(set_attr "type" "fp")])
5343 (define_insn "adddf3"
5344 [(set (match_operand:DF 0 "register_operand" "=e")
5345 (plus:DF (match_operand:DF 1 "register_operand" "e")
5346 (match_operand:DF 2 "register_operand" "e")))]
5349 [(set_attr "type" "fp")
5350 (set_attr "fptype" "double")])
5352 (define_insn "addsf3"
5353 [(set (match_operand:SF 0 "register_operand" "=f")
5354 (plus:SF (match_operand:SF 1 "register_operand" "f")
5355 (match_operand:SF 2 "register_operand" "f")))]
5358 [(set_attr "type" "fp")])
5360 (define_expand "subtf3"
5361 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5362 (minus:TF (match_operand:TF 1 "general_operand" "")
5363 (match_operand:TF 2 "general_operand" "")))]
5364 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5365 "emit_tfmode_binop (MINUS, operands); DONE;")
5367 (define_insn "*subtf3_hq"
5368 [(set (match_operand:TF 0 "register_operand" "=e")
5369 (minus:TF (match_operand:TF 1 "register_operand" "e")
5370 (match_operand:TF 2 "register_operand" "e")))]
5371 "TARGET_FPU && TARGET_HARD_QUAD"
5373 [(set_attr "type" "fp")])
5375 (define_insn "subdf3"
5376 [(set (match_operand:DF 0 "register_operand" "=e")
5377 (minus:DF (match_operand:DF 1 "register_operand" "e")
5378 (match_operand:DF 2 "register_operand" "e")))]
5381 [(set_attr "type" "fp")
5382 (set_attr "fptype" "double")])
5384 (define_insn "subsf3"
5385 [(set (match_operand:SF 0 "register_operand" "=f")
5386 (minus:SF (match_operand:SF 1 "register_operand" "f")
5387 (match_operand:SF 2 "register_operand" "f")))]
5390 [(set_attr "type" "fp")])
5392 (define_expand "multf3"
5393 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5394 (mult:TF (match_operand:TF 1 "general_operand" "")
5395 (match_operand:TF 2 "general_operand" "")))]
5396 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5397 "emit_tfmode_binop (MULT, operands); DONE;")
5399 (define_insn "*multf3_hq"
5400 [(set (match_operand:TF 0 "register_operand" "=e")
5401 (mult:TF (match_operand:TF 1 "register_operand" "e")
5402 (match_operand:TF 2 "register_operand" "e")))]
5403 "TARGET_FPU && TARGET_HARD_QUAD"
5405 [(set_attr "type" "fpmul")])
5407 (define_insn "muldf3"
5408 [(set (match_operand:DF 0 "register_operand" "=e")
5409 (mult:DF (match_operand:DF 1 "register_operand" "e")
5410 (match_operand:DF 2 "register_operand" "e")))]
5413 [(set_attr "type" "fpmul")
5414 (set_attr "fptype" "double")])
5416 (define_insn "mulsf3"
5417 [(set (match_operand:SF 0 "register_operand" "=f")
5418 (mult:SF (match_operand:SF 1 "register_operand" "f")
5419 (match_operand:SF 2 "register_operand" "f")))]
5422 [(set_attr "type" "fpmul")])
5424 (define_insn "fmadf4"
5425 [(set (match_operand:DF 0 "register_operand" "=e")
5426 (fma:DF (match_operand:DF 1 "register_operand" "e")
5427 (match_operand:DF 2 "register_operand" "e")
5428 (match_operand:DF 3 "register_operand" "e")))]
5430 "fmaddd\t%1, %2, %3, %0"
5431 [(set_attr "type" "fpmul")])
5433 (define_insn "fmsdf4"
5434 [(set (match_operand:DF 0 "register_operand" "=e")
5435 (fma:DF (match_operand:DF 1 "register_operand" "e")
5436 (match_operand:DF 2 "register_operand" "e")
5437 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5439 "fmsubd\t%1, %2, %3, %0"
5440 [(set_attr "type" "fpmul")])
5442 (define_insn "*nfmadf4"
5443 [(set (match_operand:DF 0 "register_operand" "=e")
5444 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5445 (match_operand:DF 2 "register_operand" "e")
5446 (match_operand:DF 3 "register_operand" "e"))))]
5448 "fnmaddd\t%1, %2, %3, %0"
5449 [(set_attr "type" "fpmul")])
5451 (define_insn "*nfmsdf4"
5452 [(set (match_operand:DF 0 "register_operand" "=e")
5453 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5454 (match_operand:DF 2 "register_operand" "e")
5455 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5457 "fnmsubd\t%1, %2, %3, %0"
5458 [(set_attr "type" "fpmul")])
5460 (define_insn "fmasf4"
5461 [(set (match_operand:SF 0 "register_operand" "=f")
5462 (fma:SF (match_operand:SF 1 "register_operand" "f")
5463 (match_operand:SF 2 "register_operand" "f")
5464 (match_operand:SF 3 "register_operand" "f")))]
5466 "fmadds\t%1, %2, %3, %0"
5467 [(set_attr "type" "fpmul")])
5469 (define_insn "fmssf4"
5470 [(set (match_operand:SF 0 "register_operand" "=f")
5471 (fma:SF (match_operand:SF 1 "register_operand" "f")
5472 (match_operand:SF 2 "register_operand" "f")
5473 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5475 "fmsubs\t%1, %2, %3, %0"
5476 [(set_attr "type" "fpmul")])
5478 (define_insn "*nfmasf4"
5479 [(set (match_operand:SF 0 "register_operand" "=f")
5480 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5481 (match_operand:SF 2 "register_operand" "f")
5482 (match_operand:SF 3 "register_operand" "f"))))]
5484 "fnmadds\t%1, %2, %3, %0"
5485 [(set_attr "type" "fpmul")])
5487 (define_insn "*nfmssf4"
5488 [(set (match_operand:SF 0 "register_operand" "=f")
5489 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5490 (match_operand:SF 2 "register_operand" "f")
5491 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5493 "fnmsubs\t%1, %2, %3, %0"
5494 [(set_attr "type" "fpmul")])
5496 (define_insn "*muldf3_extend"
5497 [(set (match_operand:DF 0 "register_operand" "=e")
5498 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5499 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5500 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699"
5501 "fsmuld\t%1, %2, %0"
5502 [(set_attr "type" "fpmul")
5503 (set_attr "fptype" "double")])
5505 (define_insn "*multf3_extend"
5506 [(set (match_operand:TF 0 "register_operand" "=e")
5507 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5508 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5509 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5510 "fdmulq\t%1, %2, %0"
5511 [(set_attr "type" "fpmul")])
5513 (define_expand "divtf3"
5514 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5515 (div:TF (match_operand:TF 1 "general_operand" "")
5516 (match_operand:TF 2 "general_operand" "")))]
5517 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5518 "emit_tfmode_binop (DIV, operands); DONE;")
5520 ;; don't have timing for quad-prec. divide.
5521 (define_insn "*divtf3_hq"
5522 [(set (match_operand:TF 0 "register_operand" "=e")
5523 (div:TF (match_operand:TF 1 "register_operand" "e")
5524 (match_operand:TF 2 "register_operand" "e")))]
5525 "TARGET_FPU && TARGET_HARD_QUAD"
5527 [(set_attr "type" "fpdivs")])
5529 (define_expand "divdf3"
5530 [(set (match_operand:DF 0 "register_operand" "=e")
5531 (div:DF (match_operand:DF 1 "register_operand" "e")
5532 (match_operand:DF 2 "register_operand" "e")))]
5536 (define_insn "*divdf3_nofix"
5537 [(set (match_operand:DF 0 "register_operand" "=e")
5538 (div:DF (match_operand:DF 1 "register_operand" "e")
5539 (match_operand:DF 2 "register_operand" "e")))]
5540 "TARGET_FPU && !sparc_fix_ut699"
5542 [(set_attr "type" "fpdivd")
5543 (set_attr "fptype" "double")])
5545 (define_insn "*divdf3_fix"
5546 [(set (match_operand:DF 0 "register_operand" "=e")
5547 (div:DF (match_operand:DF 1 "register_operand" "e")
5548 (match_operand:DF 2 "register_operand" "e")))]
5549 "TARGET_FPU && sparc_fix_ut699"
5550 "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]"
5551 [(set_attr "type" "fpdivd")
5552 (set_attr "fptype" "double")
5553 (set_attr "length" "2")])
5555 (define_insn "divsf3"
5556 [(set (match_operand:SF 0 "register_operand" "=f")
5557 (div:SF (match_operand:SF 1 "register_operand" "f")
5558 (match_operand:SF 2 "register_operand" "f")))]
5559 "TARGET_FPU && !sparc_fix_ut699"
5561 [(set_attr "type" "fpdivs")])
5563 (define_expand "negtf2"
5564 [(set (match_operand:TF 0 "register_operand" "")
5565 (neg:TF (match_operand:TF 1 "register_operand" "")))]
5569 (define_insn "*negtf2_hq"
5570 [(set (match_operand:TF 0 "register_operand" "=e")
5571 (neg:TF (match_operand:TF 1 "register_operand" "e")))]
5572 "TARGET_FPU && TARGET_HARD_QUAD"
5574 [(set_attr "type" "fpmove")])
5576 (define_insn_and_split "*negtf2"
5577 [(set (match_operand:TF 0 "register_operand" "=e")
5578 (neg:TF (match_operand:TF 1 "register_operand" "e")))]
5579 "TARGET_FPU && !TARGET_HARD_QUAD"
5581 "&& reload_completed"
5582 [(clobber (const_int 0))]
5584 rtx set_dest = operands[0];
5585 rtx set_src = operands[1];
5589 dest1 = gen_df_reg (set_dest, 0);
5590 dest2 = gen_df_reg (set_dest, 1);
5591 src1 = gen_df_reg (set_src, 0);
5592 src2 = gen_df_reg (set_src, 1);
5594 /* Now emit using the real source and destination we found, swapping
5595 the order if we detect overlap. */
5596 if (reg_overlap_mentioned_p (dest1, src2))
5598 emit_insn (gen_movdf (dest2, src2));
5599 emit_insn (gen_negdf2 (dest1, src1));
5603 emit_insn (gen_negdf2 (dest1, src1));
5604 if (REGNO (dest2) != REGNO (src2))
5605 emit_insn (gen_movdf (dest2, src2));
5609 [(set_attr "length" "2")])
5611 (define_expand "negdf2"
5612 [(set (match_operand:DF 0 "register_operand" "")
5613 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5617 (define_insn_and_split "*negdf2_notv9"
5618 [(set (match_operand:DF 0 "register_operand" "=e")
5619 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5620 "TARGET_FPU && !TARGET_V9"
5622 "&& reload_completed"
5623 [(clobber (const_int 0))]
5625 rtx set_dest = operands[0];
5626 rtx set_src = operands[1];
5630 dest1 = gen_highpart (SFmode, set_dest);
5631 dest2 = gen_lowpart (SFmode, set_dest);
5632 src1 = gen_highpart (SFmode, set_src);
5633 src2 = gen_lowpart (SFmode, set_src);
5635 /* Now emit using the real source and destination we found, swapping
5636 the order if we detect overlap. */
5637 if (reg_overlap_mentioned_p (dest1, src2))
5639 emit_insn (gen_movsf (dest2, src2));
5640 emit_insn (gen_negsf2 (dest1, src1));
5644 emit_insn (gen_negsf2 (dest1, src1));
5645 if (REGNO (dest2) != REGNO (src2))
5646 emit_insn (gen_movsf (dest2, src2));
5650 [(set_attr "length" "2")])
5652 (define_insn "*negdf2_v9"
5653 [(set (match_operand:DF 0 "register_operand" "=e")
5654 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5655 "TARGET_FPU && TARGET_V9"
5657 [(set_attr "type" "fpmove")
5658 (set_attr "fptype" "double")])
5660 (define_insn "negsf2"
5661 [(set (match_operand:SF 0 "register_operand" "=f")
5662 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5665 [(set_attr "type" "fpmove")])
5667 (define_expand "abstf2"
5668 [(set (match_operand:TF 0 "register_operand" "")
5669 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5673 (define_insn "*abstf2_hq"
5674 [(set (match_operand:TF 0 "register_operand" "=e")
5675 (abs:TF (match_operand:TF 1 "register_operand" "e")))]
5676 "TARGET_FPU && TARGET_HARD_QUAD"
5678 [(set_attr "type" "fpmove")])
5680 (define_insn_and_split "*abstf2"
5681 [(set (match_operand:TF 0 "register_operand" "=e")
5682 (abs:TF (match_operand:TF 1 "register_operand" "e")))]
5683 "TARGET_FPU && !TARGET_HARD_QUAD"
5685 "&& reload_completed"
5686 [(clobber (const_int 0))]
5688 rtx set_dest = operands[0];
5689 rtx set_src = operands[1];
5693 dest1 = gen_df_reg (set_dest, 0);
5694 dest2 = gen_df_reg (set_dest, 1);
5695 src1 = gen_df_reg (set_src, 0);
5696 src2 = gen_df_reg (set_src, 1);
5698 /* Now emit using the real source and destination we found, swapping
5699 the order if we detect overlap. */
5700 if (reg_overlap_mentioned_p (dest1, src2))
5702 emit_insn (gen_movdf (dest2, src2));
5703 emit_insn (gen_absdf2 (dest1, src1));
5707 emit_insn (gen_absdf2 (dest1, src1));
5708 if (REGNO (dest2) != REGNO (src2))
5709 emit_insn (gen_movdf (dest2, src2));
5713 [(set_attr "length" "2")])
5715 (define_expand "absdf2"
5716 [(set (match_operand:DF 0 "register_operand" "")
5717 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5721 (define_insn_and_split "*absdf2_notv9"
5722 [(set (match_operand:DF 0 "register_operand" "=e")
5723 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5724 "TARGET_FPU && !TARGET_V9"
5726 "&& reload_completed"
5727 [(clobber (const_int 0))]
5729 rtx set_dest = operands[0];
5730 rtx set_src = operands[1];
5734 dest1 = gen_highpart (SFmode, set_dest);
5735 dest2 = gen_lowpart (SFmode, set_dest);
5736 src1 = gen_highpart (SFmode, set_src);
5737 src2 = gen_lowpart (SFmode, set_src);
5739 /* Now emit using the real source and destination we found, swapping
5740 the order if we detect overlap. */
5741 if (reg_overlap_mentioned_p (dest1, src2))
5743 emit_insn (gen_movsf (dest2, src2));
5744 emit_insn (gen_abssf2 (dest1, src1));
5748 emit_insn (gen_abssf2 (dest1, src1));
5749 if (REGNO (dest2) != REGNO (src2))
5750 emit_insn (gen_movsf (dest2, src2));
5754 [(set_attr "length" "2")])
5756 (define_insn "*absdf2_v9"
5757 [(set (match_operand:DF 0 "register_operand" "=e")
5758 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5759 "TARGET_FPU && TARGET_V9"
5761 [(set_attr "type" "fpmove")
5762 (set_attr "fptype" "double")])
5764 (define_insn "abssf2"
5765 [(set (match_operand:SF 0 "register_operand" "=f")
5766 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5769 [(set_attr "type" "fpmove")])
5771 (define_expand "sqrttf2"
5772 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5773 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5774 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5775 "emit_tfmode_unop (SQRT, operands); DONE;")
5777 (define_insn "*sqrttf2_hq"
5778 [(set (match_operand:TF 0 "register_operand" "=e")
5779 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5780 "TARGET_FPU && TARGET_HARD_QUAD"
5782 [(set_attr "type" "fpsqrts")])
5784 (define_expand "sqrtdf2"
5785 [(set (match_operand:DF 0 "register_operand" "=e")
5786 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5790 (define_insn "*sqrtdf2_nofix"
5791 [(set (match_operand:DF 0 "register_operand" "=e")
5792 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5793 "TARGET_FPU && !sparc_fix_ut699"
5795 [(set_attr "type" "fpsqrtd")
5796 (set_attr "fptype" "double")])
5798 (define_insn "*sqrtdf2_fix"
5799 [(set (match_operand:DF 0 "register_operand" "=e")
5800 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5801 "TARGET_FPU && sparc_fix_ut699"
5802 "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]"
5803 [(set_attr "type" "fpsqrtd")
5804 (set_attr "fptype" "double")
5805 (set_attr "length" "2")])
5807 (define_insn "sqrtsf2"
5808 [(set (match_operand:SF 0 "register_operand" "=f")
5809 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5810 "TARGET_FPU && !sparc_fix_ut699"
5812 [(set_attr "type" "fpsqrts")])
5815 ;; Arithmetic shift instructions.
5817 (define_insn "ashlsi3"
5818 [(set (match_operand:SI 0 "register_operand" "=r")
5819 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5820 (match_operand:SI 2 "arith_operand" "rI")))]
5823 if (GET_CODE (operands[2]) == CONST_INT)
5824 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5825 return "sll\t%1, %2, %0";
5827 [(set_attr "type" "shift")])
5829 (define_expand "ashldi3"
5830 [(set (match_operand:DI 0 "register_operand" "=r")
5831 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5832 (match_operand:SI 2 "arith_operand" "rI")))]
5833 "TARGET_ARCH64 || TARGET_V8PLUS"
5835 if (! TARGET_ARCH64)
5837 if (GET_CODE (operands[2]) == CONST_INT)
5839 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5844 (define_insn "*ashldi3_sp64"
5845 [(set (match_operand:DI 0 "register_operand" "=r")
5846 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5847 (match_operand:SI 2 "arith_operand" "rI")))]
5850 if (GET_CODE (operands[2]) == CONST_INT)
5851 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5852 return "sllx\t%1, %2, %0";
5854 [(set_attr "type" "shift")])
5857 (define_insn "ashldi3_v8plus"
5858 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5859 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5860 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5861 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5863 "* return output_v8plus_shift (insn ,operands, \"sllx\");"
5864 [(set_attr "type" "multi")
5865 (set_attr "length" "5,5,6")])
5867 ;; Optimize (1LL<<x)-1
5868 ;; XXX this also needs to be fixed to handle equal subregs
5869 ;; XXX first before we could re-enable it.
5871 ; [(set (match_operand:DI 0 "register_operand" "=h")
5872 ; (plus:DI (ashift:DI (const_int 1)
5873 ; (match_operand:SI 1 "arith_operand" "rI"))
5875 ; "0 && TARGET_V8PLUS"
5877 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5878 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5879 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5881 ; [(set_attr "type" "multi")
5882 ; (set_attr "length" "4")])
5884 (define_insn "*cmp_cc_ashift_1"
5885 [(set (reg:CC_NOOV CC_REG)
5886 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5890 "addcc\t%0, %0, %%g0"
5891 [(set_attr "type" "compare")])
5893 (define_insn "*cmp_cc_set_ashift_1"
5894 [(set (reg:CC_NOOV CC_REG)
5895 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5898 (set (match_operand:SI 0 "register_operand" "=r")
5899 (ashift:SI (match_dup 1) (const_int 1)))]
5902 [(set_attr "type" "compare")])
5904 (define_insn "ashrsi3"
5905 [(set (match_operand:SI 0 "register_operand" "=r")
5906 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5907 (match_operand:SI 2 "arith_operand" "rI")))]
5910 if (GET_CODE (operands[2]) == CONST_INT)
5911 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5912 return "sra\t%1, %2, %0";
5914 [(set_attr "type" "shift")])
5916 (define_insn "*ashrsi3_extend"
5917 [(set (match_operand:DI 0 "register_operand" "=r")
5918 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5919 (match_operand:SI 2 "arith_operand" "r"))))]
5922 [(set_attr "type" "shift")])
5924 ;; This handles the case as above, but with constant shift instead of
5925 ;; register. Combiner "simplifies" it for us a little bit though.
5926 (define_insn "*ashrsi3_extend2"
5927 [(set (match_operand:DI 0 "register_operand" "=r")
5928 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5930 (match_operand:SI 2 "small_int_operand" "I")))]
5931 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5933 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5934 return "sra\t%1, %2, %0";
5936 [(set_attr "type" "shift")])
5938 (define_expand "ashrdi3"
5939 [(set (match_operand:DI 0 "register_operand" "=r")
5940 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5941 (match_operand:SI 2 "arith_operand" "rI")))]
5942 "TARGET_ARCH64 || TARGET_V8PLUS"
5944 if (! TARGET_ARCH64)
5946 if (GET_CODE (operands[2]) == CONST_INT)
5947 FAIL; /* prefer generic code in this case */
5948 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5953 (define_insn "*ashrdi3_sp64"
5954 [(set (match_operand:DI 0 "register_operand" "=r")
5955 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5956 (match_operand:SI 2 "arith_operand" "rI")))]
5960 if (GET_CODE (operands[2]) == CONST_INT)
5961 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5962 return "srax\t%1, %2, %0";
5964 [(set_attr "type" "shift")])
5967 (define_insn "ashrdi3_v8plus"
5968 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5969 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5970 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5971 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5973 "* return output_v8plus_shift (insn, operands, \"srax\");"
5974 [(set_attr "type" "multi")
5975 (set_attr "length" "5,5,6")])
5977 (define_insn "lshrsi3"
5978 [(set (match_operand:SI 0 "register_operand" "=r")
5979 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5980 (match_operand:SI 2 "arith_operand" "rI")))]
5983 if (GET_CODE (operands[2]) == CONST_INT)
5984 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5985 return "srl\t%1, %2, %0";
5987 [(set_attr "type" "shift")])
5989 (define_insn "*lshrsi3_extend0"
5990 [(set (match_operand:DI 0 "register_operand" "=r")
5992 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5993 (match_operand:SI 2 "arith_operand" "rI"))))]
5996 if (GET_CODE (operands[2]) == CONST_INT)
5997 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5998 return "srl\t%1, %2, %0";
6000 [(set_attr "type" "shift")])
6002 ;; This handles the case where
6003 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6004 ;; but combiner "simplifies" it for us.
6005 (define_insn "*lshrsi3_extend1"
6006 [(set (match_operand:DI 0 "register_operand" "=r")
6007 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6008 (match_operand:SI 2 "arith_operand" "r")) 0)
6009 (match_operand 3 "const_int_operand" "")))]
6010 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6012 [(set_attr "type" "shift")])
6014 ;; This handles the case where
6015 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6016 ;; but combiner "simplifies" it for us.
6017 (define_insn "*lshrsi3_extend2"
6018 [(set (match_operand:DI 0 "register_operand" "=r")
6019 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6020 (match_operand 2 "small_int_operand" "I")
6022 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6024 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6025 return "srl\t%1, %2, %0";
6027 [(set_attr "type" "shift")])
6029 (define_expand "lshrdi3"
6030 [(set (match_operand:DI 0 "register_operand" "=r")
6031 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6032 (match_operand:SI 2 "arith_operand" "rI")))]
6033 "TARGET_ARCH64 || TARGET_V8PLUS"
6035 if (! TARGET_ARCH64)
6037 if (GET_CODE (operands[2]) == CONST_INT)
6039 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6044 (define_insn "*lshrdi3_sp64"
6045 [(set (match_operand:DI 0 "register_operand" "=r")
6046 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6047 (match_operand:SI 2 "arith_operand" "rI")))]
6050 if (GET_CODE (operands[2]) == CONST_INT)
6051 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6052 return "srlx\t%1, %2, %0";
6054 [(set_attr "type" "shift")])
6057 (define_insn "lshrdi3_v8plus"
6058 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6059 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6060 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6061 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6063 "* return output_v8plus_shift (insn, operands, \"srlx\");"
6064 [(set_attr "type" "multi")
6065 (set_attr "length" "5,5,6")])
6068 [(set (match_operand:SI 0 "register_operand" "=r")
6069 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6071 (match_operand:SI 2 "small_int_operand" "I")))]
6072 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6074 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6075 return "srax\t%1, %2, %0";
6077 [(set_attr "type" "shift")])
6080 [(set (match_operand:SI 0 "register_operand" "=r")
6081 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6083 (match_operand:SI 2 "small_int_operand" "I")))]
6084 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6086 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6087 return "srlx\t%1, %2, %0";
6089 [(set_attr "type" "shift")])
6092 [(set (match_operand:SI 0 "register_operand" "=r")
6093 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6094 (match_operand:SI 2 "small_int_operand" "I")) 4)
6095 (match_operand:SI 3 "small_int_operand" "I")))]
6097 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6098 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6099 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6101 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6103 return "srax\t%1, %2, %0";
6105 [(set_attr "type" "shift")])
6108 [(set (match_operand:SI 0 "register_operand" "=r")
6109 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6110 (match_operand:SI 2 "small_int_operand" "I")) 4)
6111 (match_operand:SI 3 "small_int_operand" "I")))]
6113 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6114 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6115 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6117 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6119 return "srlx\t%1, %2, %0";
6121 [(set_attr "type" "shift")])
6124 ;; Unconditional and other jump instructions.
6126 (define_expand "jump"
6127 [(set (pc) (label_ref (match_operand 0 "" "")))]
6130 (define_insn "*jump_ubranch"
6131 [(set (pc) (label_ref (match_operand 0 "" "")))]
6133 "* return output_ubranch (operands[0], insn);"
6134 [(set_attr "type" "uncond_branch")])
6136 (define_insn "*jump_cbcond"
6137 [(set (pc) (label_ref (match_operand 0 "" "")))]
6139 "* return output_ubranch (operands[0], insn);"
6140 [(set_attr "type" "uncond_cbcond")])
6142 (define_expand "tablejump"
6143 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6144 (use (label_ref (match_operand 1 "" "")))])]
6147 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6149 /* In pic mode, our address differences are against the base of the
6150 table. Add that base value back in; CSE ought to be able to combine
6151 the two address loads. */
6155 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6157 if (CASE_VECTOR_MODE != Pmode)
6158 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6159 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6160 operands[0] = memory_address (Pmode, tmp);
6164 (define_insn "*tablejump_sp32"
6165 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6166 (use (label_ref (match_operand 1 "" "")))]
6169 [(set_attr "type" "uncond_branch")])
6171 (define_insn "*tablejump_sp64"
6172 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6173 (use (label_ref (match_operand 1 "" "")))]
6176 [(set_attr "type" "uncond_branch")])
6179 ;; Jump to subroutine instructions.
6181 (define_expand "call"
6182 ;; Note that this expression is not used for generating RTL.
6183 ;; All the RTL is generated explicitly below.
6184 [(call (match_operand 0 "call_operand" "")
6185 (match_operand 3 "" "i"))]
6186 ;; operands[2] is next_arg_register
6187 ;; operands[3] is struct_value_size_rtx.
6192 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6194 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6196 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6198 /* This is really a PIC sequence. We want to represent
6199 it as a funny jump so its delay slots can be filled.
6201 ??? But if this really *is* a CALL, will not it clobber the
6202 call-clobbered registers? We lose this if it is a JUMP_INSN.
6203 Why cannot we have delay slots filled if it were a CALL? */
6205 /* We accept negative sizes for untyped calls. */
6206 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6211 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6213 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6219 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6220 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6224 fn_rtx = operands[0];
6226 /* We accept negative sizes for untyped calls. */
6227 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6228 sparc_emit_call_insn
6231 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6233 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6236 sparc_emit_call_insn
6239 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6240 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6248 ;; We can't use the same pattern for these two insns, because then registers
6249 ;; in the address may not be properly reloaded.
6251 (define_insn "*call_address_sp32"
6252 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6253 (match_operand 1 "" ""))
6254 (clobber (reg:SI O7_REG))]
6255 ;;- Do not use operand 1 for most machines.
6258 [(set_attr "type" "call")])
6260 (define_insn "*call_symbolic_sp32"
6261 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6262 (match_operand 1 "" ""))
6263 (clobber (reg:SI O7_REG))]
6264 ;;- Do not use operand 1 for most machines.
6267 [(set_attr "type" "call")])
6269 (define_insn "*call_address_sp64"
6270 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6271 (match_operand 1 "" ""))
6272 (clobber (reg:DI O7_REG))]
6273 ;;- Do not use operand 1 for most machines.
6276 [(set_attr "type" "call")])
6278 (define_insn "*call_symbolic_sp64"
6279 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6280 (match_operand 1 "" ""))
6281 (clobber (reg:DI O7_REG))]
6282 ;;- Do not use operand 1 for most machines.
6285 [(set_attr "type" "call")])
6287 ;; This is a call that wants a structure value.
6288 ;; There is no such critter for v9 (??? we may need one anyway).
6289 (define_insn "*call_address_struct_value_sp32"
6290 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6291 (match_operand 1 "" ""))
6292 (match_operand 2 "immediate_operand" "")
6293 (clobber (reg:SI O7_REG))]
6294 ;;- Do not use operand 1 for most machines.
6295 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6297 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6298 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6300 [(set_attr "type" "call_no_delay_slot")
6301 (set_attr "length" "3")])
6303 ;; This is a call that wants a structure value.
6304 ;; There is no such critter for v9 (??? we may need one anyway).
6305 (define_insn "*call_symbolic_struct_value_sp32"
6306 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6307 (match_operand 1 "" ""))
6308 (match_operand 2 "immediate_operand" "")
6309 (clobber (reg:SI O7_REG))]
6310 ;;- Do not use operand 1 for most machines.
6311 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6313 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6314 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6316 [(set_attr "type" "call_no_delay_slot")
6317 (set_attr "length" "3")])
6319 ;; This is a call that may want a structure value. This is used for
6321 (define_insn "*call_address_untyped_struct_value_sp32"
6322 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6323 (match_operand 1 "" ""))
6324 (match_operand 2 "immediate_operand" "")
6325 (clobber (reg:SI O7_REG))]
6326 ;;- Do not use operand 1 for most machines.
6327 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6328 "call\t%a0, %1\n\t nop\n\tnop"
6329 [(set_attr "type" "call_no_delay_slot")
6330 (set_attr "length" "3")])
6332 ;; This is a call that may want a structure value. This is used for
6334 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6335 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6336 (match_operand 1 "" ""))
6337 (match_operand 2 "immediate_operand" "")
6338 (clobber (reg:SI O7_REG))]
6339 ;;- Do not use operand 1 for most machines.
6340 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6341 "call\t%a0, %1\n\t nop\n\tnop"
6342 [(set_attr "type" "call_no_delay_slot")
6343 (set_attr "length" "3")])
6345 (define_expand "call_value"
6346 ;; Note that this expression is not used for generating RTL.
6347 ;; All the RTL is generated explicitly below.
6348 [(set (match_operand 0 "register_operand" "=rf")
6349 (call (match_operand 1 "" "")
6350 (match_operand 4 "" "")))]
6351 ;; operand 2 is stack_size_rtx
6352 ;; operand 3 is next_arg_register
6358 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6360 fn_rtx = operands[1];
6363 gen_rtx_SET (VOIDmode, operands[0],
6364 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6365 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6367 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6372 (define_insn "*call_value_address_sp32"
6373 [(set (match_operand 0 "" "=rf")
6374 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6375 (match_operand 2 "" "")))
6376 (clobber (reg:SI O7_REG))]
6377 ;;- Do not use operand 2 for most machines.
6380 [(set_attr "type" "call")])
6382 (define_insn "*call_value_symbolic_sp32"
6383 [(set (match_operand 0 "" "=rf")
6384 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6385 (match_operand 2 "" "")))
6386 (clobber (reg:SI O7_REG))]
6387 ;;- Do not use operand 2 for most machines.
6390 [(set_attr "type" "call")])
6392 (define_insn "*call_value_address_sp64"
6393 [(set (match_operand 0 "" "")
6394 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6395 (match_operand 2 "" "")))
6396 (clobber (reg:DI O7_REG))]
6397 ;;- Do not use operand 2 for most machines.
6400 [(set_attr "type" "call")])
6402 (define_insn "*call_value_symbolic_sp64"
6403 [(set (match_operand 0 "" "")
6404 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6405 (match_operand 2 "" "")))
6406 (clobber (reg:DI O7_REG))]
6407 ;;- Do not use operand 2 for most machines.
6410 [(set_attr "type" "call")])
6412 (define_expand "untyped_call"
6413 [(parallel [(call (match_operand 0 "" "")
6415 (match_operand:BLK 1 "memory_operand" "")
6416 (match_operand 2 "" "")])]
6419 rtx valreg1 = gen_rtx_REG (DImode, 8);
6420 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6421 rtx result = operands[1];
6423 /* Pass constm1 to indicate that it may expect a structure value, but
6424 we don't know what size it is. */
6425 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6427 /* Save the function value registers. */
6428 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6429 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6432 /* The optimizer does not know that the call sets the function value
6433 registers we stored in the result block. We avoid problems by
6434 claiming that all hard registers are used and clobbered at this
6436 emit_insn (gen_blockage ());
6441 ;; Tail call instructions.
6443 (define_expand "sibcall"
6444 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6449 (define_insn "*sibcall_symbolic_sp32"
6450 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6451 (match_operand 1 "" ""))
6454 "* return output_sibcall(insn, operands[0]);"
6455 [(set_attr "type" "sibcall")])
6457 (define_insn "*sibcall_symbolic_sp64"
6458 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6459 (match_operand 1 "" ""))
6462 "* return output_sibcall(insn, operands[0]);"
6463 [(set_attr "type" "sibcall")])
6465 (define_expand "sibcall_value"
6466 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6467 (call (match_operand 1 "" "") (const_int 0)))
6472 (define_insn "*sibcall_value_symbolic_sp32"
6473 [(set (match_operand 0 "" "=rf")
6474 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6475 (match_operand 2 "" "")))
6478 "* return output_sibcall(insn, operands[1]);"
6479 [(set_attr "type" "sibcall")])
6481 (define_insn "*sibcall_value_symbolic_sp64"
6482 [(set (match_operand 0 "" "")
6483 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6484 (match_operand 2 "" "")))
6487 "* return output_sibcall(insn, operands[1]);"
6488 [(set_attr "type" "sibcall")])
6491 ;; Special instructions.
6493 (define_expand "prologue"
6498 sparc_flat_expand_prologue ();
6500 sparc_expand_prologue ();
6504 ;; The "register window save" insn is modelled as follows. The dwarf2
6505 ;; information is manually added in emit_window_save.
6507 (define_insn "window_save"
6509 [(match_operand 0 "arith_operand" "rI")]
6512 "save\t%%sp, %0, %%sp"
6513 [(set_attr "type" "savew")])
6515 (define_expand "epilogue"
6520 sparc_flat_expand_epilogue (false);
6522 sparc_expand_epilogue (false);
6525 (define_expand "sibcall_epilogue"
6530 sparc_flat_expand_epilogue (false);
6532 sparc_expand_epilogue (false);
6536 (define_expand "eh_return"
6537 [(use (match_operand 0 "general_operand" ""))]
6540 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6541 emit_jump_insn (gen_eh_return_internal ());
6546 (define_insn_and_split "eh_return_internal"
6550 "epilogue_completed"
6554 sparc_flat_expand_epilogue (true);
6556 sparc_expand_epilogue (true);
6559 (define_expand "return"
6561 "sparc_can_use_return_insn_p ()"
6564 (define_insn "*return_internal"
6567 "* return output_return (insn);"
6568 [(set_attr "type" "return")
6569 (set (attr "length")
6570 (cond [(eq_attr "calls_eh_return" "true")
6571 (if_then_else (eq_attr "delayed_branch" "true")
6572 (if_then_else (ior (eq_attr "isa" "v9")
6573 (eq_attr "flat" "true"))
6576 (if_then_else (eq_attr "flat" "true")
6579 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6580 (if_then_else (eq_attr "empty_delay_slot" "true")
6583 (eq_attr "empty_delay_slot" "true")
6584 (if_then_else (eq_attr "delayed_branch" "true")
6589 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6590 ;; all of memory. This blocks insns from being moved across this point.
6592 (define_insn "blockage"
6593 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6596 [(set_attr "length" "0")])
6598 ;; Do not schedule instructions accessing memory before this point.
6600 (define_expand "frame_blockage"
6602 (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
6605 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6606 MEM_VOLATILE_P (operands[0]) = 1;
6607 operands[1] = stack_pointer_rtx;
6610 (define_insn "*frame_blockage<P:mode>"
6611 [(set (match_operand:BLK 0 "" "")
6612 (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
6615 [(set_attr "length" "0")])
6617 (define_expand "probe_stack"
6618 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6622 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6625 (define_insn "probe_stack_range<P:mode>"
6626 [(set (match_operand:P 0 "register_operand" "=r")
6627 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6628 (match_operand:P 2 "register_operand" "r")]
6629 UNSPECV_PROBE_STACK_RANGE))]
6631 "* return output_probe_stack_range (operands[0], operands[2]);"
6632 [(set_attr "type" "multi")])
6634 ;; Prepare to return any type including a structure value.
6636 (define_expand "untyped_return"
6637 [(match_operand:BLK 0 "memory_operand" "")
6638 (match_operand 1 "" "")]
6641 rtx valreg1 = gen_rtx_REG (DImode, 24);
6642 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6643 rtx result = operands[0];
6645 if (! TARGET_ARCH64)
6647 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6648 rtx value = gen_reg_rtx (SImode);
6650 /* Fetch the instruction where we will return to and see if it's an unimp
6651 instruction (the most significant 10 bits will be zero). If so,
6652 update the return address to skip the unimp instruction. */
6653 emit_move_insn (value,
6654 gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8)));
6655 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6656 emit_insn (gen_update_return (rtnreg, value));
6659 /* Reload the function value registers. */
6660 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6661 emit_move_insn (valreg2,
6662 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6664 /* Put USE insns before the return. */
6668 /* Construct the return. */
6669 expand_naked_return ();
6674 ;; Adjust the return address conditionally. If the value of op1 is equal
6675 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6676 ;; This is technically *half* the check required by the 32-bit SPARC
6677 ;; psABI. This check only ensures that an "unimp" insn was written by
6678 ;; the caller, but doesn't check to see if the expected size matches
6679 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6680 ;; only used by the above code "untyped_return".
6682 (define_insn "update_return"
6683 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6684 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6687 if (flag_delayed_branch)
6688 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6690 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6692 [(set (attr "type") (const_string "multi"))
6693 (set (attr "length")
6694 (if_then_else (eq_attr "delayed_branch" "true")
6703 (define_expand "indirect_jump"
6704 [(set (pc) (match_operand 0 "address_operand" "p"))]
6708 (define_insn "*branch_sp32"
6709 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6712 [(set_attr "type" "uncond_branch")])
6714 (define_insn "*branch_sp64"
6715 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6718 [(set_attr "type" "uncond_branch")])
6720 (define_expand "save_stack_nonlocal"
6721 [(set (match_operand 0 "memory_operand" "")
6722 (match_operand 1 "register_operand" ""))
6723 (set (match_dup 2) (match_dup 3))]
6726 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6727 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6728 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6731 (define_expand "restore_stack_nonlocal"
6732 [(set (match_operand 0 "register_operand" "")
6733 (match_operand 1 "memory_operand" ""))]
6736 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6739 (define_expand "nonlocal_goto"
6740 [(match_operand 0 "general_operand" "")
6741 (match_operand 1 "general_operand" "")
6742 (match_operand 2 "memory_operand" "")
6743 (match_operand 3 "memory_operand" "")]
6746 rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6747 rtx r_label = copy_to_reg (operands[1]);
6748 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6749 rtx r_fp = operands[3];
6750 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6752 /* We need to flush all the register windows so that their contents will
6753 be re-synchronized by the restore insn of the target function. */
6755 emit_insn (gen_flush_register_windows ());
6757 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6758 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6760 /* Restore frame pointer for containing function. */
6761 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6762 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6763 emit_move_insn (i7, r_i7);
6765 /* USE of hard_frame_pointer_rtx added for consistency;
6766 not clear if really needed. */
6767 emit_use (hard_frame_pointer_rtx);
6768 emit_use (stack_pointer_rtx);
6771 emit_jump_insn (gen_indirect_jump (r_label));
6776 (define_expand "builtin_setjmp_receiver"
6777 [(label_ref (match_operand 0 "" ""))]
6780 load_got_register ();
6784 ;; Special insn to flush register windows.
6786 (define_insn "flush_register_windows"
6787 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6789 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6790 [(set_attr "type" "flushw")])
6792 ;; Special pattern for the FLUSH instruction.
6794 (define_insn "flush<P:mode>"
6795 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6797 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6798 [(set_attr "type" "iflush")])
6800 ;; Special insns to load and store the 32-bit FP Status Register.
6802 (define_insn "ldfsr"
6803 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)]
6806 [(set_attr "type" "load")])
6808 (define_insn "stfsr"
6809 [(set (match_operand:SI 0 "memory_operand" "=m")
6810 (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))]
6813 [(set_attr "type" "store")])
6816 ;; Find first set instructions.
6818 ;; The scan instruction searches from the most significant bit while ffs
6819 ;; searches from the least significant bit. The bit index and treatment of
6820 ;; zero also differ. It takes at least 7 instructions to get the proper
6821 ;; result. Here is an obvious 8 instruction sequence.
6824 (define_insn "ffssi2"
6825 [(set (match_operand:SI 0 "register_operand" "=&r")
6826 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6827 (clobber (match_scratch:SI 2 "=&r"))]
6828 "TARGET_SPARCLITE || TARGET_SPARCLET"
6830 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";
6832 [(set_attr "type" "multi")
6833 (set_attr "length" "8")])
6835 (define_expand "popcountdi2"
6836 [(set (match_operand:DI 0 "register_operand" "")
6837 (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6840 if (! TARGET_ARCH64)
6842 emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6847 (define_insn "*popcountdi_sp64"
6848 [(set (match_operand:DI 0 "register_operand" "=r")
6849 (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6850 "TARGET_POPC && TARGET_ARCH64"
6853 (define_insn "popcountdi_v8plus"
6854 [(set (match_operand:DI 0 "register_operand" "=r")
6855 (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6856 (clobber (match_scratch:SI 2 "=&h"))]
6857 "TARGET_POPC && ! TARGET_ARCH64"
6859 if (sparc_check_64 (operands[1], insn) <= 0)
6860 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6861 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6863 [(set_attr "type" "multi")
6864 (set_attr "length" "5")])
6866 (define_expand "popcountsi2"
6868 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6869 (set (match_operand:SI 0 "register_operand" "")
6870 (truncate:SI (popcount:DI (match_dup 2))))]
6873 if (! TARGET_ARCH64)
6875 emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6879 operands[2] = gen_reg_rtx (DImode);
6882 (define_insn "*popcountsi_sp64"
6883 [(set (match_operand:SI 0 "register_operand" "=r")
6885 (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6886 "TARGET_POPC && TARGET_ARCH64"
6889 (define_insn "popcountsi_v8plus"
6890 [(set (match_operand:SI 0 "register_operand" "=r")
6891 (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6892 "TARGET_POPC && ! TARGET_ARCH64"
6894 if (sparc_check_64 (operands[1], insn) <= 0)
6895 output_asm_insn ("srl\t%1, 0, %1", operands);
6896 return "popc\t%1, %0";
6898 [(set_attr "type" "multi")
6899 (set_attr "length" "2")])
6901 (define_expand "clzdi2"
6902 [(set (match_operand:DI 0 "register_operand" "")
6903 (clz:DI (match_operand:DI 1 "register_operand" "")))]
6906 if (! TARGET_ARCH64)
6908 emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6913 (define_insn "*clzdi_sp64"
6914 [(set (match_operand:DI 0 "register_operand" "=r")
6915 (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6916 "TARGET_VIS3 && TARGET_ARCH64"
6919 (define_insn "clzdi_v8plus"
6920 [(set (match_operand:DI 0 "register_operand" "=r")
6921 (clz:DI (match_operand:DI 1 "register_operand" "r")))
6922 (clobber (match_scratch:SI 2 "=&h"))]
6923 "TARGET_VIS3 && ! TARGET_ARCH64"
6925 if (sparc_check_64 (operands[1], insn) <= 0)
6926 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6927 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6929 [(set_attr "type" "multi")
6930 (set_attr "length" "5")])
6932 (define_expand "clzsi2"
6934 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6936 (truncate:SI (clz:DI (match_dup 2))))
6937 (set (match_operand:SI 0 "register_operand" "")
6938 (minus:SI (match_dup 3) (const_int 32)))]
6941 if (! TARGET_ARCH64)
6943 emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6948 operands[2] = gen_reg_rtx (DImode);
6949 operands[3] = gen_reg_rtx (SImode);
6953 (define_insn "*clzsi_sp64"
6954 [(set (match_operand:SI 0 "register_operand" "=r")
6956 (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6957 "TARGET_VIS3 && TARGET_ARCH64"
6960 (define_insn "clzsi_v8plus"
6961 [(set (match_operand:SI 0 "register_operand" "=r")
6962 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6963 "TARGET_VIS3 && ! TARGET_ARCH64"
6965 if (sparc_check_64 (operands[1], insn) <= 0)
6966 output_asm_insn ("srl\t%1, 0, %1", operands);
6967 return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6969 [(set_attr "type" "multi")
6970 (set_attr "length" "3")])
6973 ;; Peepholes go at the end.
6975 ;; Optimize consecutive loads or stores into ldd and std when possible.
6976 ;; The conditions in which we do this are very restricted and are
6977 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6980 [(set (match_operand:SI 0 "memory_operand" "")
6982 (set (match_operand:SI 1 "memory_operand" "")
6985 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6986 [(set (match_dup 0) (const_int 0))]
6988 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode);
6992 [(set (match_operand:SI 0 "memory_operand" "")
6994 (set (match_operand:SI 1 "memory_operand" "")
6997 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6998 [(set (match_dup 1) (const_int 0))]
7000 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode);
7004 [(set (match_operand:SI 0 "register_operand" "")
7005 (match_operand:SI 1 "memory_operand" ""))
7006 (set (match_operand:SI 2 "register_operand" "")
7007 (match_operand:SI 3 "memory_operand" ""))]
7008 "registers_ok_for_ldd_peep (operands[0], operands[2])
7009 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7010 [(set (match_dup 0) (match_dup 1))]
7012 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode);
7013 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
7017 [(set (match_operand:SI 0 "memory_operand" "")
7018 (match_operand:SI 1 "register_operand" ""))
7019 (set (match_operand:SI 2 "memory_operand" "")
7020 (match_operand:SI 3 "register_operand" ""))]
7021 "registers_ok_for_ldd_peep (operands[1], operands[3])
7022 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7023 [(set (match_dup 0) (match_dup 1))]
7025 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode);
7026 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
7030 [(set (match_operand:SF 0 "register_operand" "")
7031 (match_operand:SF 1 "memory_operand" ""))
7032 (set (match_operand:SF 2 "register_operand" "")
7033 (match_operand:SF 3 "memory_operand" ""))]
7034 "registers_ok_for_ldd_peep (operands[0], operands[2])
7035 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7036 [(set (match_dup 0) (match_dup 1))]
7038 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode);
7039 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));
7043 [(set (match_operand:SF 0 "memory_operand" "")
7044 (match_operand:SF 1 "register_operand" ""))
7045 (set (match_operand:SF 2 "memory_operand" "")
7046 (match_operand:SF 3 "register_operand" ""))]
7047 "registers_ok_for_ldd_peep (operands[1], operands[3])
7048 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7049 [(set (match_dup 0) (match_dup 1))]
7051 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode);
7052 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));
7056 [(set (match_operand:SI 0 "register_operand" "")
7057 (match_operand:SI 1 "memory_operand" ""))
7058 (set (match_operand:SI 2 "register_operand" "")
7059 (match_operand:SI 3 "memory_operand" ""))]
7060 "registers_ok_for_ldd_peep (operands[2], operands[0])
7061 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7062 [(set (match_dup 2) (match_dup 3))]
7064 operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode);
7065 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));
7069 [(set (match_operand:SI 0 "memory_operand" "")
7070 (match_operand:SI 1 "register_operand" ""))
7071 (set (match_operand:SI 2 "memory_operand" "")
7072 (match_operand:SI 3 "register_operand" ""))]
7073 "registers_ok_for_ldd_peep (operands[3], operands[1])
7074 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7075 [(set (match_dup 2) (match_dup 3))]
7077 operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DImode);
7078 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7082 [(set (match_operand:SF 0 "register_operand" "")
7083 (match_operand:SF 1 "memory_operand" ""))
7084 (set (match_operand:SF 2 "register_operand" "")
7085 (match_operand:SF 3 "memory_operand" ""))]
7086 "registers_ok_for_ldd_peep (operands[2], operands[0])
7087 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7088 [(set (match_dup 2) (match_dup 3))]
7090 operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode);
7091 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));
7095 [(set (match_operand:SF 0 "memory_operand" "")
7096 (match_operand:SF 1 "register_operand" ""))
7097 (set (match_operand:SF 2 "memory_operand" "")
7098 (match_operand:SF 3 "register_operand" ""))]
7099 "registers_ok_for_ldd_peep (operands[3], operands[1])
7100 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7101 [(set (match_dup 2) (match_dup 3))]
7103 operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode);
7104 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));
7107 ;; Optimize the case of following a reg-reg move with a test
7108 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7109 ;; This can result from a float to fix conversion.
7112 [(set (match_operand:SI 0 "register_operand" "")
7113 (match_operand:SI 1 "register_operand" ""))
7114 (set (reg:CC CC_REG)
7115 (compare:CC (match_operand:SI 2 "register_operand" "")
7117 "(rtx_equal_p (operands[2], operands[0])
7118 || rtx_equal_p (operands[2], operands[1]))
7119 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7120 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7121 [(parallel [(set (match_dup 0) (match_dup 1))
7122 (set (reg:CC CC_REG)
7123 (compare:CC (match_dup 1) (const_int 0)))])]
7127 [(set (match_operand:DI 0 "register_operand" "")
7128 (match_operand:DI 1 "register_operand" ""))
7129 (set (reg:CCX CC_REG)
7130 (compare:CCX (match_operand:DI 2 "register_operand" "")
7133 && (rtx_equal_p (operands[2], operands[0])
7134 || rtx_equal_p (operands[2], operands[1]))
7135 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7136 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7137 [(parallel [(set (match_dup 0) (match_dup 1))
7138 (set (reg:CCX CC_REG)
7139 (compare:CCX (match_dup 1) (const_int 0)))])]
7143 ;; Prefetch instructions.
7145 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7146 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7147 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7149 (define_expand "prefetch"
7150 [(match_operand 0 "address_operand" "")
7151 (match_operand 1 "const_int_operand" "")
7152 (match_operand 2 "const_int_operand" "")]
7156 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7158 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7162 (define_insn "prefetch_64"
7163 [(prefetch (match_operand:DI 0 "address_operand" "p")
7164 (match_operand:DI 1 "const_int_operand" "n")
7165 (match_operand:DI 2 "const_int_operand" "n"))]
7168 static const char * const prefetch_instr[2][2] = {
7170 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7171 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7174 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7175 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7178 int read_or_write = INTVAL (operands[1]);
7179 int locality = INTVAL (operands[2]);
7181 gcc_assert (read_or_write == 0 || read_or_write == 1);
7182 gcc_assert (locality >= 0 && locality < 4);
7183 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7185 [(set_attr "type" "load")])
7187 (define_insn "prefetch_32"
7188 [(prefetch (match_operand:SI 0 "address_operand" "p")
7189 (match_operand:SI 1 "const_int_operand" "n")
7190 (match_operand:SI 2 "const_int_operand" "n"))]
7193 static const char * const prefetch_instr[2][2] = {
7195 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7196 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7199 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7200 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7203 int read_or_write = INTVAL (operands[1]);
7204 int locality = INTVAL (operands[2]);
7206 gcc_assert (read_or_write == 0 || read_or_write == 1);
7207 gcc_assert (locality >= 0 && locality < 4);
7208 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7210 [(set_attr "type" "load")])
7213 ;; Trap instructions.
7216 [(trap_if (const_int 1) (const_int 5))]
7219 [(set_attr "type" "trap")])
7221 (define_expand "ctrapsi4"
7222 [(trap_if (match_operator 0 "noov_compare_operator"
7223 [(match_operand:SI 1 "compare_operand" "")
7224 (match_operand:SI 2 "arith_operand" "")])
7225 (match_operand 3 "arith_operand"))]
7227 "operands[1] = gen_compare_reg (operands[0]);
7228 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7230 operands[2] = const0_rtx;")
7232 (define_expand "ctrapdi4"
7233 [(trap_if (match_operator 0 "noov_compare_operator"
7234 [(match_operand:DI 1 "compare_operand" "")
7235 (match_operand:DI 2 "arith_operand" "")])
7236 (match_operand 3 "arith_operand"))]
7238 "operands[1] = gen_compare_reg (operands[0]);
7239 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7241 operands[2] = const0_rtx;")
7245 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7246 (match_operand:SI 1 "arith_operand" "rM"))]
7250 return "t%C0\t%%icc, %1";
7254 [(set_attr "type" "trap")])
7257 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7258 (match_operand:SI 1 "arith_operand" "rM"))]
7261 [(set_attr "type" "trap")])
7264 ;; TLS support instructions.
7266 (define_insn "tgd_hi22"
7267 [(set (match_operand:SI 0 "register_operand" "=r")
7268 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7271 "sethi\\t%%tgd_hi22(%a1), %0")
7273 (define_insn "tgd_lo10"
7274 [(set (match_operand:SI 0 "register_operand" "=r")
7275 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7276 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7279 "add\\t%1, %%tgd_lo10(%a2), %0")
7281 (define_insn "tgd_add32"
7282 [(set (match_operand:SI 0 "register_operand" "=r")
7283 (plus:SI (match_operand:SI 1 "register_operand" "r")
7284 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7285 (match_operand 3 "tgd_symbolic_operand" "")]
7287 "TARGET_TLS && TARGET_ARCH32"
7288 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7290 (define_insn "tgd_add64"
7291 [(set (match_operand:DI 0 "register_operand" "=r")
7292 (plus:DI (match_operand:DI 1 "register_operand" "r")
7293 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7294 (match_operand 3 "tgd_symbolic_operand" "")]
7296 "TARGET_TLS && TARGET_ARCH64"
7297 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7299 (define_insn "tgd_call32"
7300 [(set (match_operand 0 "register_operand" "=r")
7301 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7302 (match_operand 2 "tgd_symbolic_operand" "")]
7304 (match_operand 3 "" "")))
7305 (clobber (reg:SI O7_REG))]
7306 "TARGET_TLS && TARGET_ARCH32"
7307 "call\t%a1, %%tgd_call(%a2)%#"
7308 [(set_attr "type" "call")])
7310 (define_insn "tgd_call64"
7311 [(set (match_operand 0 "register_operand" "=r")
7312 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7313 (match_operand 2 "tgd_symbolic_operand" "")]
7315 (match_operand 3 "" "")))
7316 (clobber (reg:DI O7_REG))]
7317 "TARGET_TLS && TARGET_ARCH64"
7318 "call\t%a1, %%tgd_call(%a2)%#"
7319 [(set_attr "type" "call")])
7321 (define_insn "tldm_hi22"
7322 [(set (match_operand:SI 0 "register_operand" "=r")
7323 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7325 "sethi\\t%%tldm_hi22(%&), %0")
7327 (define_insn "tldm_lo10"
7328 [(set (match_operand:SI 0 "register_operand" "=r")
7329 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7330 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7332 "add\\t%1, %%tldm_lo10(%&), %0")
7334 (define_insn "tldm_add32"
7335 [(set (match_operand:SI 0 "register_operand" "=r")
7336 (plus:SI (match_operand:SI 1 "register_operand" "r")
7337 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7339 "TARGET_TLS && TARGET_ARCH32"
7340 "add\\t%1, %2, %0, %%tldm_add(%&)")
7342 (define_insn "tldm_add64"
7343 [(set (match_operand:DI 0 "register_operand" "=r")
7344 (plus:DI (match_operand:DI 1 "register_operand" "r")
7345 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7347 "TARGET_TLS && TARGET_ARCH64"
7348 "add\\t%1, %2, %0, %%tldm_add(%&)")
7350 (define_insn "tldm_call32"
7351 [(set (match_operand 0 "register_operand" "=r")
7352 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7354 (match_operand 2 "" "")))
7355 (clobber (reg:SI O7_REG))]
7356 "TARGET_TLS && TARGET_ARCH32"
7357 "call\t%a1, %%tldm_call(%&)%#"
7358 [(set_attr "type" "call")])
7360 (define_insn "tldm_call64"
7361 [(set (match_operand 0 "register_operand" "=r")
7362 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7364 (match_operand 2 "" "")))
7365 (clobber (reg:DI O7_REG))]
7366 "TARGET_TLS && TARGET_ARCH64"
7367 "call\t%a1, %%tldm_call(%&)%#"
7368 [(set_attr "type" "call")])
7370 (define_insn "tldo_hix22"
7371 [(set (match_operand:SI 0 "register_operand" "=r")
7372 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7375 "sethi\\t%%tldo_hix22(%a1), %0")
7377 (define_insn "tldo_lox10"
7378 [(set (match_operand:SI 0 "register_operand" "=r")
7379 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7380 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7383 "xor\\t%1, %%tldo_lox10(%a2), %0")
7385 (define_insn "tldo_add32"
7386 [(set (match_operand:SI 0 "register_operand" "=r")
7387 (plus:SI (match_operand:SI 1 "register_operand" "r")
7388 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7389 (match_operand 3 "tld_symbolic_operand" "")]
7391 "TARGET_TLS && TARGET_ARCH32"
7392 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7394 (define_insn "tldo_add64"
7395 [(set (match_operand:DI 0 "register_operand" "=r")
7396 (plus:DI (match_operand:DI 1 "register_operand" "r")
7397 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7398 (match_operand 3 "tld_symbolic_operand" "")]
7400 "TARGET_TLS && TARGET_ARCH64"
7401 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7403 (define_insn "tie_hi22"
7404 [(set (match_operand:SI 0 "register_operand" "=r")
7405 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7408 "sethi\\t%%tie_hi22(%a1), %0")
7410 (define_insn "tie_lo10"
7411 [(set (match_operand:SI 0 "register_operand" "=r")
7412 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7413 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7416 "add\\t%1, %%tie_lo10(%a2), %0")
7418 (define_insn "tie_ld32"
7419 [(set (match_operand:SI 0 "register_operand" "=r")
7420 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7421 (match_operand:SI 2 "register_operand" "r")
7422 (match_operand 3 "tie_symbolic_operand" "")]
7424 "TARGET_TLS && TARGET_ARCH32"
7425 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7426 [(set_attr "type" "load")])
7428 (define_insn "tie_ld64"
7429 [(set (match_operand:DI 0 "register_operand" "=r")
7430 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7431 (match_operand:SI 2 "register_operand" "r")
7432 (match_operand 3 "tie_symbolic_operand" "")]
7434 "TARGET_TLS && TARGET_ARCH64"
7435 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7436 [(set_attr "type" "load")])
7438 (define_insn "tie_add32"
7439 [(set (match_operand:SI 0 "register_operand" "=r")
7440 (plus:SI (match_operand:SI 1 "register_operand" "r")
7441 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7442 (match_operand 3 "tie_symbolic_operand" "")]
7444 "TARGET_SUN_TLS && TARGET_ARCH32"
7445 "add\\t%1, %2, %0, %%tie_add(%a3)")
7447 (define_insn "tie_add64"
7448 [(set (match_operand:DI 0 "register_operand" "=r")
7449 (plus:DI (match_operand:DI 1 "register_operand" "r")
7450 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7451 (match_operand 3 "tie_symbolic_operand" "")]
7453 "TARGET_SUN_TLS && TARGET_ARCH64"
7454 "add\\t%1, %2, %0, %%tie_add(%a3)")
7456 (define_insn "tle_hix22_sp32"
7457 [(set (match_operand:SI 0 "register_operand" "=r")
7458 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7460 "TARGET_TLS && TARGET_ARCH32"
7461 "sethi\\t%%tle_hix22(%a1), %0")
7463 (define_insn "tle_lox10_sp32"
7464 [(set (match_operand:SI 0 "register_operand" "=r")
7465 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7466 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7468 "TARGET_TLS && TARGET_ARCH32"
7469 "xor\\t%1, %%tle_lox10(%a2), %0")
7471 (define_insn "tle_hix22_sp64"
7472 [(set (match_operand:DI 0 "register_operand" "=r")
7473 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7475 "TARGET_TLS && TARGET_ARCH64"
7476 "sethi\\t%%tle_hix22(%a1), %0")
7478 (define_insn "tle_lox10_sp64"
7479 [(set (match_operand:DI 0 "register_operand" "=r")
7480 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7481 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7483 "TARGET_TLS && TARGET_ARCH64"
7484 "xor\\t%1, %%tle_lox10(%a2), %0")
7486 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7487 (define_insn "*tldo_ldub_sp32"
7488 [(set (match_operand:QI 0 "register_operand" "=r")
7489 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7490 (match_operand 3 "tld_symbolic_operand" "")]
7492 (match_operand:SI 1 "register_operand" "r"))))]
7493 "TARGET_TLS && TARGET_ARCH32"
7494 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7495 [(set_attr "type" "load")
7496 (set_attr "us3load_type" "3cycle")])
7498 (define_insn "*tldo_ldub1_sp32"
7499 [(set (match_operand:HI 0 "register_operand" "=r")
7500 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7501 (match_operand 3 "tld_symbolic_operand" "")]
7503 (match_operand:SI 1 "register_operand" "r")))))]
7504 "TARGET_TLS && TARGET_ARCH32"
7505 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7506 [(set_attr "type" "load")
7507 (set_attr "us3load_type" "3cycle")])
7509 (define_insn "*tldo_ldub2_sp32"
7510 [(set (match_operand:SI 0 "register_operand" "=r")
7511 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7512 (match_operand 3 "tld_symbolic_operand" "")]
7514 (match_operand:SI 1 "register_operand" "r")))))]
7515 "TARGET_TLS && TARGET_ARCH32"
7516 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7517 [(set_attr "type" "load")
7518 (set_attr "us3load_type" "3cycle")])
7520 (define_insn "*tldo_ldsb1_sp32"
7521 [(set (match_operand:HI 0 "register_operand" "=r")
7522 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7523 (match_operand 3 "tld_symbolic_operand" "")]
7525 (match_operand:SI 1 "register_operand" "r")))))]
7526 "TARGET_TLS && TARGET_ARCH32"
7527 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7528 [(set_attr "type" "sload")
7529 (set_attr "us3load_type" "3cycle")])
7531 (define_insn "*tldo_ldsb2_sp32"
7532 [(set (match_operand:SI 0 "register_operand" "=r")
7533 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7534 (match_operand 3 "tld_symbolic_operand" "")]
7536 (match_operand:SI 1 "register_operand" "r")))))]
7537 "TARGET_TLS && TARGET_ARCH32"
7538 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7539 [(set_attr "type" "sload")
7540 (set_attr "us3load_type" "3cycle")])
7542 (define_insn "*tldo_ldub_sp64"
7543 [(set (match_operand:QI 0 "register_operand" "=r")
7544 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7545 (match_operand 3 "tld_symbolic_operand" "")]
7547 (match_operand:DI 1 "register_operand" "r"))))]
7548 "TARGET_TLS && TARGET_ARCH64"
7549 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7550 [(set_attr "type" "load")
7551 (set_attr "us3load_type" "3cycle")])
7553 (define_insn "*tldo_ldub1_sp64"
7554 [(set (match_operand:HI 0 "register_operand" "=r")
7555 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7556 (match_operand 3 "tld_symbolic_operand" "")]
7558 (match_operand:DI 1 "register_operand" "r")))))]
7559 "TARGET_TLS && TARGET_ARCH64"
7560 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7561 [(set_attr "type" "load")
7562 (set_attr "us3load_type" "3cycle")])
7564 (define_insn "*tldo_ldub2_sp64"
7565 [(set (match_operand:SI 0 "register_operand" "=r")
7566 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7567 (match_operand 3 "tld_symbolic_operand" "")]
7569 (match_operand:DI 1 "register_operand" "r")))))]
7570 "TARGET_TLS && TARGET_ARCH64"
7571 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7572 [(set_attr "type" "load")
7573 (set_attr "us3load_type" "3cycle")])
7575 (define_insn "*tldo_ldub3_sp64"
7576 [(set (match_operand:DI 0 "register_operand" "=r")
7577 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7578 (match_operand 3 "tld_symbolic_operand" "")]
7580 (match_operand:DI 1 "register_operand" "r")))))]
7581 "TARGET_TLS && TARGET_ARCH64"
7582 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7583 [(set_attr "type" "load")
7584 (set_attr "us3load_type" "3cycle")])
7586 (define_insn "*tldo_ldsb1_sp64"
7587 [(set (match_operand:HI 0 "register_operand" "=r")
7588 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7589 (match_operand 3 "tld_symbolic_operand" "")]
7591 (match_operand:DI 1 "register_operand" "r")))))]
7592 "TARGET_TLS && TARGET_ARCH64"
7593 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7594 [(set_attr "type" "sload")
7595 (set_attr "us3load_type" "3cycle")])
7597 (define_insn "*tldo_ldsb2_sp64"
7598 [(set (match_operand:SI 0 "register_operand" "=r")
7599 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7600 (match_operand 3 "tld_symbolic_operand" "")]
7602 (match_operand:DI 1 "register_operand" "r")))))]
7603 "TARGET_TLS && TARGET_ARCH64"
7604 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7605 [(set_attr "type" "sload")
7606 (set_attr "us3load_type" "3cycle")])
7608 (define_insn "*tldo_ldsb3_sp64"
7609 [(set (match_operand:DI 0 "register_operand" "=r")
7610 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7611 (match_operand 3 "tld_symbolic_operand" "")]
7613 (match_operand:DI 1 "register_operand" "r")))))]
7614 "TARGET_TLS && TARGET_ARCH64"
7615 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7616 [(set_attr "type" "sload")
7617 (set_attr "us3load_type" "3cycle")])
7619 (define_insn "*tldo_lduh_sp32"
7620 [(set (match_operand:HI 0 "register_operand" "=r")
7621 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7622 (match_operand 3 "tld_symbolic_operand" "")]
7624 (match_operand:SI 1 "register_operand" "r"))))]
7625 "TARGET_TLS && TARGET_ARCH32"
7626 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7627 [(set_attr "type" "load")
7628 (set_attr "us3load_type" "3cycle")])
7630 (define_insn "*tldo_lduh1_sp32"
7631 [(set (match_operand:SI 0 "register_operand" "=r")
7632 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7633 (match_operand 3 "tld_symbolic_operand" "")]
7635 (match_operand:SI 1 "register_operand" "r")))))]
7636 "TARGET_TLS && TARGET_ARCH32"
7637 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7638 [(set_attr "type" "load")
7639 (set_attr "us3load_type" "3cycle")])
7641 (define_insn "*tldo_ldsh1_sp32"
7642 [(set (match_operand:SI 0 "register_operand" "=r")
7643 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7644 (match_operand 3 "tld_symbolic_operand" "")]
7646 (match_operand:SI 1 "register_operand" "r")))))]
7647 "TARGET_TLS && TARGET_ARCH32"
7648 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7649 [(set_attr "type" "sload")
7650 (set_attr "us3load_type" "3cycle")])
7652 (define_insn "*tldo_lduh_sp64"
7653 [(set (match_operand:HI 0 "register_operand" "=r")
7654 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7655 (match_operand 3 "tld_symbolic_operand" "")]
7657 (match_operand:DI 1 "register_operand" "r"))))]
7658 "TARGET_TLS && TARGET_ARCH64"
7659 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7660 [(set_attr "type" "load")
7661 (set_attr "us3load_type" "3cycle")])
7663 (define_insn "*tldo_lduh1_sp64"
7664 [(set (match_operand:SI 0 "register_operand" "=r")
7665 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7666 (match_operand 3 "tld_symbolic_operand" "")]
7668 (match_operand:DI 1 "register_operand" "r")))))]
7669 "TARGET_TLS && TARGET_ARCH64"
7670 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7671 [(set_attr "type" "load")
7672 (set_attr "us3load_type" "3cycle")])
7674 (define_insn "*tldo_lduh2_sp64"
7675 [(set (match_operand:DI 0 "register_operand" "=r")
7676 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7677 (match_operand 3 "tld_symbolic_operand" "")]
7679 (match_operand:DI 1 "register_operand" "r")))))]
7680 "TARGET_TLS && TARGET_ARCH64"
7681 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7682 [(set_attr "type" "load")
7683 (set_attr "us3load_type" "3cycle")])
7685 (define_insn "*tldo_ldsh1_sp64"
7686 [(set (match_operand:SI 0 "register_operand" "=r")
7687 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7688 (match_operand 3 "tld_symbolic_operand" "")]
7690 (match_operand:DI 1 "register_operand" "r")))))]
7691 "TARGET_TLS && TARGET_ARCH64"
7692 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7693 [(set_attr "type" "sload")
7694 (set_attr "us3load_type" "3cycle")])
7696 (define_insn "*tldo_ldsh2_sp64"
7697 [(set (match_operand:DI 0 "register_operand" "=r")
7698 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7699 (match_operand 3 "tld_symbolic_operand" "")]
7701 (match_operand:DI 1 "register_operand" "r")))))]
7702 "TARGET_TLS && TARGET_ARCH64"
7703 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7704 [(set_attr "type" "sload")
7705 (set_attr "us3load_type" "3cycle")])
7707 (define_insn "*tldo_lduw_sp32"
7708 [(set (match_operand:SI 0 "register_operand" "=r")
7709 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7710 (match_operand 3 "tld_symbolic_operand" "")]
7712 (match_operand:SI 1 "register_operand" "r"))))]
7713 "TARGET_TLS && TARGET_ARCH32"
7714 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7715 [(set_attr "type" "load")])
7717 (define_insn "*tldo_lduw_sp64"
7718 [(set (match_operand:SI 0 "register_operand" "=r")
7719 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7720 (match_operand 3 "tld_symbolic_operand" "")]
7722 (match_operand:DI 1 "register_operand" "r"))))]
7723 "TARGET_TLS && TARGET_ARCH64"
7724 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7725 [(set_attr "type" "load")])
7727 (define_insn "*tldo_lduw1_sp64"
7728 [(set (match_operand:DI 0 "register_operand" "=r")
7729 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7730 (match_operand 3 "tld_symbolic_operand" "")]
7732 (match_operand:DI 1 "register_operand" "r")))))]
7733 "TARGET_TLS && TARGET_ARCH64"
7734 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7735 [(set_attr "type" "load")])
7737 (define_insn "*tldo_ldsw1_sp64"
7738 [(set (match_operand:DI 0 "register_operand" "=r")
7739 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7740 (match_operand 3 "tld_symbolic_operand" "")]
7742 (match_operand:DI 1 "register_operand" "r")))))]
7743 "TARGET_TLS && TARGET_ARCH64"
7744 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7745 [(set_attr "type" "sload")
7746 (set_attr "us3load_type" "3cycle")])
7748 (define_insn "*tldo_ldx_sp64"
7749 [(set (match_operand:DI 0 "register_operand" "=r")
7750 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7751 (match_operand 3 "tld_symbolic_operand" "")]
7753 (match_operand:DI 1 "register_operand" "r"))))]
7754 "TARGET_TLS && TARGET_ARCH64"
7755 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7756 [(set_attr "type" "load")])
7758 (define_insn "*tldo_stb_sp32"
7759 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7760 (match_operand 3 "tld_symbolic_operand" "")]
7762 (match_operand:SI 1 "register_operand" "r")))
7763 (match_operand:QI 0 "register_operand" "r"))]
7764 "TARGET_TLS && TARGET_ARCH32"
7765 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7766 [(set_attr "type" "store")])
7768 (define_insn "*tldo_stb_sp64"
7769 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7770 (match_operand 3 "tld_symbolic_operand" "")]
7772 (match_operand:DI 1 "register_operand" "r")))
7773 (match_operand:QI 0 "register_operand" "r"))]
7774 "TARGET_TLS && TARGET_ARCH64"
7775 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7776 [(set_attr "type" "store")])
7778 (define_insn "*tldo_sth_sp32"
7779 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7780 (match_operand 3 "tld_symbolic_operand" "")]
7782 (match_operand:SI 1 "register_operand" "r")))
7783 (match_operand:HI 0 "register_operand" "r"))]
7784 "TARGET_TLS && TARGET_ARCH32"
7785 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7786 [(set_attr "type" "store")])
7788 (define_insn "*tldo_sth_sp64"
7789 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7790 (match_operand 3 "tld_symbolic_operand" "")]
7792 (match_operand:DI 1 "register_operand" "r")))
7793 (match_operand:HI 0 "register_operand" "r"))]
7794 "TARGET_TLS && TARGET_ARCH64"
7795 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7796 [(set_attr "type" "store")])
7798 (define_insn "*tldo_stw_sp32"
7799 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7800 (match_operand 3 "tld_symbolic_operand" "")]
7802 (match_operand:SI 1 "register_operand" "r")))
7803 (match_operand:SI 0 "register_operand" "r"))]
7804 "TARGET_TLS && TARGET_ARCH32"
7805 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7806 [(set_attr "type" "store")])
7808 (define_insn "*tldo_stw_sp64"
7809 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7810 (match_operand 3 "tld_symbolic_operand" "")]
7812 (match_operand:DI 1 "register_operand" "r")))
7813 (match_operand:SI 0 "register_operand" "r"))]
7814 "TARGET_TLS && TARGET_ARCH64"
7815 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7816 [(set_attr "type" "store")])
7818 (define_insn "*tldo_stx_sp64"
7819 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7820 (match_operand 3 "tld_symbolic_operand" "")]
7822 (match_operand:DI 1 "register_operand" "r")))
7823 (match_operand:DI 0 "register_operand" "r"))]
7824 "TARGET_TLS && TARGET_ARCH64"
7825 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7826 [(set_attr "type" "store")])
7829 ;; Stack protector instructions.
7831 (define_expand "stack_protect_set"
7832 [(match_operand 0 "memory_operand" "")
7833 (match_operand 1 "memory_operand" "")]
7836 #ifdef TARGET_THREAD_SSP_OFFSET
7837 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7838 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7839 operands[1] = gen_rtx_MEM (Pmode, addr);
7842 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7844 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7848 (define_insn "stack_protect_setsi"
7849 [(set (match_operand:SI 0 "memory_operand" "=m")
7850 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7851 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7853 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7854 [(set_attr "type" "multi")
7855 (set_attr "length" "3")])
7857 (define_insn "stack_protect_setdi"
7858 [(set (match_operand:DI 0 "memory_operand" "=m")
7859 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7860 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7862 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7863 [(set_attr "type" "multi")
7864 (set_attr "length" "3")])
7866 (define_expand "stack_protect_test"
7867 [(match_operand 0 "memory_operand" "")
7868 (match_operand 1 "memory_operand" "")
7869 (match_operand 2 "" "")]
7873 #ifdef TARGET_THREAD_SSP_OFFSET
7874 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7875 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7876 operands[1] = gen_rtx_MEM (Pmode, addr);
7880 result = gen_reg_rtx (Pmode);
7881 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7882 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7883 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7887 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7888 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7889 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7890 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7895 (define_insn "stack_protect_testsi"
7896 [(set (reg:CC CC_REG)
7897 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7898 (match_operand:SI 1 "memory_operand" "m")]
7900 (set (match_scratch:SI 3 "=r") (const_int 0))
7901 (clobber (match_scratch:SI 2 "=&r"))]
7903 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7904 [(set_attr "type" "multi")
7905 (set_attr "length" "4")])
7907 (define_insn "stack_protect_testdi"
7908 [(set (match_operand:DI 0 "register_operand" "=&r")
7909 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7910 (match_operand:DI 2 "memory_operand" "m")]
7912 (set (match_scratch:DI 3 "=r") (const_int 0))]
7914 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7915 [(set_attr "type" "multi")
7916 (set_attr "length" "4")])
7918 ;; Vector instructions.
7920 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7921 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7922 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7924 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
7925 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7926 (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7927 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7928 (V1DI "double") (V2SI "double") (V4HI "double")
7931 (define_expand "mov<VMALL:mode>"
7932 [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7933 (match_operand:VMALL 1 "general_operand" ""))]
7936 if (sparc_expand_move (<VMALL:MODE>mode, operands))
7940 (define_insn "*mov<VM32:mode>_insn"
7941 [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
7942 (match_operand:VM32 1 "input_operand" "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
7944 && (register_operand (operands[0], <VM32:MODE>mode)
7945 || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7958 [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv")
7959 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
7961 (define_insn "*mov<VM64:mode>_insn_sp64"
7962 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
7963 (match_operand:VM64 1 "input_operand" "Y,C,e,m,e,Y, m,*r, e,*r,*r"))]
7966 && (register_operand (operands[0], <VM64:MODE>mode)
7967 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7980 [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*")
7981 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
7983 (define_insn "*mov<VM64:mode>_insn_sp32"
7984 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
7985 (match_operand:VM64 1 "input_operand" "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
7988 && (register_operand (operands[0], <VM64:MODE>mode)
7989 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
8003 [(set_attr "type" "visl,visl,vismv,*,*,fpload,fpstore,store,load,store,*,*")
8004 (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
8005 (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
8008 [(set (match_operand:VM64 0 "memory_operand" "")
8009 (match_operand:VM64 1 "register_operand" ""))]
8013 && (((REGNO (operands[1]) % 2) != 0)
8014 || ! mem_min_alignment (operands[0], 8))
8015 && offsettable_memref_p (operands[0])"
8016 [(clobber (const_int 0))]
8020 word0 = adjust_address (operands[0], SImode, 0);
8021 word1 = adjust_address (operands[0], SImode, 4);
8023 emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
8024 emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
8029 [(set (match_operand:VM64 0 "register_operand" "")
8030 (match_operand:VM64 1 "register_operand" ""))]
8034 && sparc_split_regreg_legitimate (operands[0], operands[1])"
8035 [(clobber (const_int 0))]
8037 rtx set_dest = operands[0];
8038 rtx set_src = operands[1];
8042 dest1 = gen_highpart (SImode, set_dest);
8043 dest2 = gen_lowpart (SImode, set_dest);
8044 src1 = gen_highpart (SImode, set_src);
8045 src2 = gen_lowpart (SImode, set_src);
8047 /* Now emit using the real source and destination we found, swapping
8048 the order if we detect overlap. */
8049 if (reg_overlap_mentioned_p (dest1, src2))
8051 emit_insn (gen_movsi (dest2, src2));
8052 emit_insn (gen_movsi (dest1, src1));
8056 emit_insn (gen_movsi (dest1, src1));
8057 emit_insn (gen_movsi (dest2, src2));
8062 (define_expand "vec_init<mode>"
8063 [(match_operand:VMALL 0 "register_operand" "")
8064 (match_operand:VMALL 1 "" "")]
8067 sparc_expand_vector_init (operands[0], operands[1]);
8071 (define_code_iterator plusminus [plus minus])
8072 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
8074 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
8076 (define_insn "<plusminus_insn><mode>3"
8077 [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
8078 (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
8079 (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
8081 "fp<plusminus_insn><vbits>\t%1, %2, %0"
8082 [(set_attr "type" "fga")
8083 (set_attr "fptype" "<vfptype>")])
8085 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8086 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
8087 (V1DI "") (V2SI "") (V4HI "") (V8QI "")])
8088 (define_code_iterator vlop [ior and xor])
8089 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
8090 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
8092 (define_insn "<code><mode>3"
8093 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8094 (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8095 (match_operand:VL 2 "register_operand" "<vconstr>")))]
8097 "f<vlinsn><vlsuf>\t%1, %2, %0"
8098 [(set_attr "type" "visl")
8099 (set_attr "fptype" "<vfptype>")])
8101 (define_insn "*not_<code><mode>3"
8102 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8103 (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8104 (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8106 "f<vlninsn><vlsuf>\t%1, %2, %0"
8107 [(set_attr "type" "visl")
8108 (set_attr "fptype" "<vfptype>")])
8110 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8111 (define_insn "*nand<mode>_vis"
8112 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8113 (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8114 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8116 "fnand<vlsuf>\t%1, %2, %0"
8117 [(set_attr "type" "visl")
8118 (set_attr "fptype" "<vfptype>")])
8120 (define_code_iterator vlnotop [ior and])
8122 (define_insn "*<code>_not1<mode>_vis"
8123 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8124 (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8125 (match_operand:VL 2 "register_operand" "<vconstr>")))]
8127 "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
8128 [(set_attr "type" "visl")
8129 (set_attr "fptype" "<vfptype>")])
8131 (define_insn "*<code>_not2<mode>_vis"
8132 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8133 (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8134 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8136 "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
8137 [(set_attr "type" "visl")
8138 (set_attr "fptype" "<vfptype>")])
8140 (define_insn "one_cmpl<mode>2"
8141 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8142 (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
8144 "fnot1<vlsuf>\t%1, %0"
8145 [(set_attr "type" "visl")
8146 (set_attr "fptype" "<vfptype>")])
8148 ;; Hard to generate VIS instructions. We have builtins for these.
8150 (define_insn "fpack16_vis"
8151 [(set (match_operand:V4QI 0 "register_operand" "=f")
8152 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
8157 [(set_attr "type" "fgm_pack")
8158 (set_attr "fptype" "double")])
8160 (define_insn "fpackfix_vis"
8161 [(set (match_operand:V2HI 0 "register_operand" "=f")
8162 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
8167 [(set_attr "type" "fgm_pack")
8168 (set_attr "fptype" "double")])
8170 (define_insn "fpack32_vis"
8171 [(set (match_operand:V8QI 0 "register_operand" "=e")
8172 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8173 (match_operand:V8QI 2 "register_operand" "e")
8177 "fpack32\t%1, %2, %0"
8178 [(set_attr "type" "fgm_pack")
8179 (set_attr "fptype" "double")])
8181 (define_insn "fexpand_vis"
8182 [(set (match_operand:V4HI 0 "register_operand" "=e")
8183 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8187 [(set_attr "type" "fga")
8188 (set_attr "fptype" "double")])
8190 (define_insn "fpmerge_vis"
8191 [(set (match_operand:V8QI 0 "register_operand" "=e")
8193 (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8194 (match_operand:V4QI 2 "register_operand" "f"))
8195 (parallel [(const_int 0) (const_int 4)
8196 (const_int 1) (const_int 5)
8197 (const_int 2) (const_int 6)
8198 (const_int 3) (const_int 7)])))]
8200 "fpmerge\t%1, %2, %0"
8201 [(set_attr "type" "fga")
8202 (set_attr "fptype" "double")])
8204 (define_insn "vec_interleave_lowv8qi"
8205 [(set (match_operand:V8QI 0 "register_operand" "=e")
8207 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8208 (match_operand:V8QI 2 "register_operand" "f"))
8209 (parallel [(const_int 0) (const_int 8)
8210 (const_int 1) (const_int 9)
8211 (const_int 2) (const_int 10)
8212 (const_int 3) (const_int 11)])))]
8214 "fpmerge\t%L1, %L2, %0"
8215 [(set_attr "type" "fga")
8216 (set_attr "fptype" "double")])
8218 (define_insn "vec_interleave_highv8qi"
8219 [(set (match_operand:V8QI 0 "register_operand" "=e")
8221 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8222 (match_operand:V8QI 2 "register_operand" "f"))
8223 (parallel [(const_int 4) (const_int 12)
8224 (const_int 5) (const_int 13)
8225 (const_int 6) (const_int 14)
8226 (const_int 7) (const_int 15)])))]
8228 "fpmerge\t%H1, %H2, %0"
8229 [(set_attr "type" "fga")
8230 (set_attr "fptype" "double")])
8232 ;; Partitioned multiply instructions
8233 (define_insn "fmul8x16_vis"
8234 [(set (match_operand:V4HI 0 "register_operand" "=e")
8235 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8236 (match_operand:V4HI 2 "register_operand" "e")]
8239 "fmul8x16\t%1, %2, %0"
8240 [(set_attr "type" "fgm_mul")
8241 (set_attr "fptype" "double")])
8243 (define_insn "fmul8x16au_vis"
8244 [(set (match_operand:V4HI 0 "register_operand" "=e")
8245 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8246 (match_operand:V2HI 2 "register_operand" "f")]
8249 "fmul8x16au\t%1, %2, %0"
8250 [(set_attr "type" "fgm_mul")
8251 (set_attr "fptype" "double")])
8253 (define_insn "fmul8x16al_vis"
8254 [(set (match_operand:V4HI 0 "register_operand" "=e")
8255 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8256 (match_operand:V2HI 2 "register_operand" "f")]
8259 "fmul8x16al\t%1, %2, %0"
8260 [(set_attr "type" "fgm_mul")
8261 (set_attr "fptype" "double")])
8263 (define_insn "fmul8sux16_vis"
8264 [(set (match_operand:V4HI 0 "register_operand" "=e")
8265 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8266 (match_operand:V4HI 2 "register_operand" "e")]
8269 "fmul8sux16\t%1, %2, %0"
8270 [(set_attr "type" "fgm_mul")
8271 (set_attr "fptype" "double")])
8273 (define_insn "fmul8ulx16_vis"
8274 [(set (match_operand:V4HI 0 "register_operand" "=e")
8275 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8276 (match_operand:V4HI 2 "register_operand" "e")]
8279 "fmul8ulx16\t%1, %2, %0"
8280 [(set_attr "type" "fgm_mul")
8281 (set_attr "fptype" "double")])
8283 (define_insn "fmuld8sux16_vis"
8284 [(set (match_operand:V2SI 0 "register_operand" "=e")
8285 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8286 (match_operand:V2HI 2 "register_operand" "f")]
8289 "fmuld8sux16\t%1, %2, %0"
8290 [(set_attr "type" "fgm_mul")
8291 (set_attr "fptype" "double")])
8293 (define_insn "fmuld8ulx16_vis"
8294 [(set (match_operand:V2SI 0 "register_operand" "=e")
8295 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8296 (match_operand:V2HI 2 "register_operand" "f")]
8299 "fmuld8ulx16\t%1, %2, %0"
8300 [(set_attr "type" "fgm_mul")
8301 (set_attr "fptype" "double")])
8303 (define_expand "wrgsr_vis"
8304 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8307 if (! TARGET_ARCH64)
8309 emit_insn (gen_wrgsr_v8plus (operands[0]));
8314 (define_insn "*wrgsr_sp64"
8315 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8316 "TARGET_VIS && TARGET_ARCH64"
8317 "wr\t%%g0, %0, %%gsr"
8318 [(set_attr "type" "gsr")])
8320 (define_insn "wrgsr_v8plus"
8321 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8322 (clobber (match_scratch:SI 1 "=X,&h"))]
8323 "TARGET_VIS && ! TARGET_ARCH64"
8325 if (GET_CODE (operands[0]) == CONST_INT
8326 || sparc_check_64 (operands[0], insn))
8327 return "wr\t%%g0, %0, %%gsr";
8329 output_asm_insn("srl\t%L0, 0, %L0", operands);
8330 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8332 [(set_attr "type" "multi")])
8334 (define_expand "rdgsr_vis"
8335 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8338 if (! TARGET_ARCH64)
8340 emit_insn (gen_rdgsr_v8plus (operands[0]));
8345 (define_insn "*rdgsr_sp64"
8346 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8347 "TARGET_VIS && TARGET_ARCH64"
8349 [(set_attr "type" "gsr")])
8351 (define_insn "rdgsr_v8plus"
8352 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8353 (clobber (match_scratch:SI 1 "=&h"))]
8354 "TARGET_VIS && ! TARGET_ARCH64"
8356 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8358 [(set_attr "type" "multi")])
8360 ;; Using faligndata only makes sense after an alignaddr since the choice of
8361 ;; bytes to take out of each operand is dependent on the results of the last
8363 (define_insn "faligndata<VM64:mode>_vis"
8364 [(set (match_operand:VM64 0 "register_operand" "=e")
8365 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8366 (match_operand:VM64 2 "register_operand" "e")
8370 "faligndata\t%1, %2, %0"
8371 [(set_attr "type" "fga")
8372 (set_attr "fptype" "double")])
8374 (define_insn "alignaddrsi_vis"
8375 [(set (match_operand:SI 0 "register_operand" "=r")
8376 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8377 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8378 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8379 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8381 "alignaddr\t%r1, %r2, %0"
8382 [(set_attr "type" "gsr")])
8384 (define_insn "alignaddrdi_vis"
8385 [(set (match_operand:DI 0 "register_operand" "=r")
8386 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8387 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8388 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8389 (plus:DI (match_dup 1) (match_dup 2)))]
8391 "alignaddr\t%r1, %r2, %0"
8392 [(set_attr "type" "gsr")])
8394 (define_insn "alignaddrlsi_vis"
8395 [(set (match_operand:SI 0 "register_operand" "=r")
8396 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8397 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8398 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8399 (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8402 "alignaddrl\t%r1, %r2, %0"
8403 [(set_attr "type" "gsr")])
8405 (define_insn "alignaddrldi_vis"
8406 [(set (match_operand:DI 0 "register_operand" "=r")
8407 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8408 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8409 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8410 (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8413 "alignaddrl\t%r1, %r2, %0"
8414 [(set_attr "type" "gsr")])
8416 (define_insn "pdist_vis"
8417 [(set (match_operand:DI 0 "register_operand" "=e")
8418 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8419 (match_operand:V8QI 2 "register_operand" "e")
8420 (match_operand:DI 3 "register_operand" "0")]
8424 [(set_attr "type" "pdist")
8425 (set_attr "fptype" "double")])
8427 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8428 ;; with the same operands.
8429 (define_insn "edge8<P:mode>_vis"
8430 [(set (reg:CC_NOOV CC_REG)
8431 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8432 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8434 (set (match_operand:P 0 "register_operand" "=r")
8435 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8437 "edge8\t%r1, %r2, %0"
8438 [(set_attr "type" "edge")])
8440 (define_insn "edge8l<P:mode>_vis"
8441 [(set (reg:CC_NOOV CC_REG)
8442 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8443 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8445 (set (match_operand:P 0 "register_operand" "=r")
8446 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8448 "edge8l\t%r1, %r2, %0"
8449 [(set_attr "type" "edge")])
8451 (define_insn "edge16<P:mode>_vis"
8452 [(set (reg:CC_NOOV CC_REG)
8453 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8454 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8456 (set (match_operand:P 0 "register_operand" "=r")
8457 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8459 "edge16\t%r1, %r2, %0"
8460 [(set_attr "type" "edge")])
8462 (define_insn "edge16l<P:mode>_vis"
8463 [(set (reg:CC_NOOV CC_REG)
8464 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8465 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8467 (set (match_operand:P 0 "register_operand" "=r")
8468 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8470 "edge16l\t%r1, %r2, %0"
8471 [(set_attr "type" "edge")])
8473 (define_insn "edge32<P:mode>_vis"
8474 [(set (reg:CC_NOOV CC_REG)
8475 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8476 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8478 (set (match_operand:P 0 "register_operand" "=r")
8479 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8481 "edge32\t%r1, %r2, %0"
8482 [(set_attr "type" "edge")])
8484 (define_insn "edge32l<P:mode>_vis"
8485 [(set (reg:CC_NOOV CC_REG)
8486 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8487 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8489 (set (match_operand:P 0 "register_operand" "=r")
8490 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8492 "edge32l\t%r1, %r2, %0"
8493 [(set_attr "type" "edge")])
8495 (define_code_iterator gcond [le ne gt eq])
8496 (define_mode_iterator GCM [V4HI V2SI])
8497 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8499 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8500 [(set (match_operand:P 0 "register_operand" "=r")
8501 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8502 (match_operand:GCM 2 "register_operand" "e"))]
8505 "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8506 [(set_attr "type" "visl")
8507 (set_attr "fptype" "double")])
8509 (define_expand "vcond<mode><mode>"
8510 [(match_operand:GCM 0 "register_operand" "")
8511 (match_operand:GCM 1 "register_operand" "")
8512 (match_operand:GCM 2 "register_operand" "")
8513 (match_operator 3 ""
8514 [(match_operand:GCM 4 "register_operand" "")
8515 (match_operand:GCM 5 "register_operand" "")])]
8518 sparc_expand_vcond (<MODE>mode, operands,
8519 UNSPEC_CMASK<gcm_name>,
8524 (define_expand "vconduv8qiv8qi"
8525 [(match_operand:V8QI 0 "register_operand" "")
8526 (match_operand:V8QI 1 "register_operand" "")
8527 (match_operand:V8QI 2 "register_operand" "")
8528 (match_operator 3 ""
8529 [(match_operand:V8QI 4 "register_operand" "")
8530 (match_operand:V8QI 5 "register_operand" "")])]
8533 sparc_expand_vcond (V8QImode, operands,
8539 (define_insn "array8<P:mode>_vis"
8540 [(set (match_operand:P 0 "register_operand" "=r")
8541 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8542 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8545 "array8\t%r1, %r2, %0"
8546 [(set_attr "type" "array")])
8548 (define_insn "array16<P:mode>_vis"
8549 [(set (match_operand:P 0 "register_operand" "=r")
8550 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8551 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8554 "array16\t%r1, %r2, %0"
8555 [(set_attr "type" "array")])
8557 (define_insn "array32<P:mode>_vis"
8558 [(set (match_operand:P 0 "register_operand" "=r")
8559 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8560 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8563 "array32\t%r1, %r2, %0"
8564 [(set_attr "type" "array")])
8566 (define_insn "bmaskdi_vis"
8567 [(set (match_operand:DI 0 "register_operand" "=r")
8568 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8569 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8570 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8571 (plus:DI (match_dup 1) (match_dup 2)))]
8573 "bmask\t%r1, %r2, %0"
8574 [(set_attr "type" "array")])
8576 (define_insn "bmasksi_vis"
8577 [(set (match_operand:SI 0 "register_operand" "=r")
8578 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8579 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8580 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8581 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8583 "bmask\t%r1, %r2, %0"
8584 [(set_attr "type" "array")])
8586 (define_insn "bshuffle<VM64:mode>_vis"
8587 [(set (match_operand:VM64 0 "register_operand" "=e")
8588 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8589 (match_operand:VM64 2 "register_operand" "e")
8593 "bshuffle\t%1, %2, %0"
8594 [(set_attr "type" "fga")
8595 (set_attr "fptype" "double")])
8597 ;; The rtl expanders will happily convert constant permutations on other
8598 ;; modes down to V8QI. Rely on this to avoid the complexity of the byte
8599 ;; order of the permutation.
8600 (define_expand "vec_perm_constv8qi"
8601 [(match_operand:V8QI 0 "register_operand" "")
8602 (match_operand:V8QI 1 "register_operand" "")
8603 (match_operand:V8QI 2 "register_operand" "")
8604 (match_operand:V8QI 3 "" "")]
8607 unsigned int i, mask;
8608 rtx sel = operands[3];
8610 for (i = mask = 0; i < 8; ++i)
8611 mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8612 sel = force_reg (SImode, gen_int_mode (mask, SImode));
8614 emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx));
8615 emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8619 ;; Unlike constant permutation, we can vastly simplify the compression of
8620 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8621 ;; width of the input is.
8622 (define_expand "vec_perm<mode>"
8623 [(match_operand:VM64 0 "register_operand" "")
8624 (match_operand:VM64 1 "register_operand" "")
8625 (match_operand:VM64 2 "register_operand" "")
8626 (match_operand:VM64 3 "register_operand" "")]
8629 sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8630 emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8634 ;; VIS 2.0 adds edge variants which do not set the condition codes
8635 (define_insn "edge8n<P:mode>_vis"
8636 [(set (match_operand:P 0 "register_operand" "=r")
8637 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8638 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8641 "edge8n\t%r1, %r2, %0"
8642 [(set_attr "type" "edgen")])
8644 (define_insn "edge8ln<P:mode>_vis"
8645 [(set (match_operand:P 0 "register_operand" "=r")
8646 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8647 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8650 "edge8ln\t%r1, %r2, %0"
8651 [(set_attr "type" "edgen")])
8653 (define_insn "edge16n<P:mode>_vis"
8654 [(set (match_operand:P 0 "register_operand" "=r")
8655 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8656 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8659 "edge16n\t%r1, %r2, %0"
8660 [(set_attr "type" "edgen")])
8662 (define_insn "edge16ln<P:mode>_vis"
8663 [(set (match_operand:P 0 "register_operand" "=r")
8664 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8665 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8668 "edge16ln\t%r1, %r2, %0"
8669 [(set_attr "type" "edgen")])
8671 (define_insn "edge32n<P:mode>_vis"
8672 [(set (match_operand:P 0 "register_operand" "=r")
8673 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8674 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8677 "edge32n\t%r1, %r2, %0"
8678 [(set_attr "type" "edgen")])
8680 (define_insn "edge32ln<P:mode>_vis"
8681 [(set (match_operand:P 0 "register_operand" "=r")
8682 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8683 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8686 "edge32ln\t%r1, %r2, %0"
8687 [(set_attr "type" "edge")])
8689 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8690 (define_insn "cmask8<P:mode>_vis"
8691 [(set (reg:DI GSR_REG)
8692 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8697 [(set_attr "type" "fga")])
8699 (define_insn "cmask16<P:mode>_vis"
8700 [(set (reg:DI GSR_REG)
8701 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8706 [(set_attr "type" "fga")])
8708 (define_insn "cmask32<P:mode>_vis"
8709 [(set (reg:DI GSR_REG)
8710 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8715 [(set_attr "type" "fga")])
8717 (define_insn "fchksm16_vis"
8718 [(set (match_operand:V4HI 0 "register_operand" "=e")
8719 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8720 (match_operand:V4HI 2 "register_operand" "e")]
8723 "fchksm16\t%1, %2, %0"
8724 [(set_attr "type" "fga")])
8726 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8727 (define_code_attr vis3_shift_insn
8728 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8729 (define_code_attr vis3_shift_patname
8730 [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8732 (define_insn "v<vis3_shift_patname><mode>3"
8733 [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8734 (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8735 (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8737 "<vis3_shift_insn><vbits>\t%1, %2, %0"
8738 [(set_attr "type" "fga")])
8740 (define_insn "pdistn<mode>_vis"
8741 [(set (match_operand:P 0 "register_operand" "=r")
8742 (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8743 (match_operand:V8QI 2 "register_operand" "e")]
8746 "pdistn\t%1, %2, %0"
8747 [(set_attr "type" "pdistn")
8748 (set_attr "fptype" "double")])
8750 (define_insn "fmean16_vis"
8751 [(set (match_operand:V4HI 0 "register_operand" "=e")
8757 (match_operand:V4HI 1 "register_operand" "e"))
8759 (match_operand:V4HI 2 "register_operand" "e")))
8760 (const_vector:V4SI [(const_int 1) (const_int 1)
8761 (const_int 1) (const_int 1)]))
8764 "fmean16\t%1, %2, %0"
8765 [(set_attr "type" "fga")])
8767 (define_insn "fp<plusminus_insn>64_vis"
8768 [(set (match_operand:V1DI 0 "register_operand" "=e")
8769 (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8770 (match_operand:V1DI 2 "register_operand" "e")))]
8772 "fp<plusminus_insn>64\t%1, %2, %0"
8773 [(set_attr "type" "fga")])
8775 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8776 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8777 (define_code_attr vis3_addsub_ss_insn
8778 [(ss_plus "fpadds") (ss_minus "fpsubs")])
8779 (define_code_attr vis3_addsub_ss_patname
8780 [(ss_plus "ssadd") (ss_minus "sssub")])
8782 (define_insn "<vis3_addsub_ss_patname><mode>3"
8783 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8784 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8785 (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8787 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
8788 [(set_attr "type" "fga")])
8790 (define_insn "fucmp<code>8<P:mode>_vis"
8791 [(set (match_operand:P 0 "register_operand" "=r")
8792 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8793 (match_operand:V8QI 2 "register_operand" "e"))]
8796 "fucmp<code>8\t%1, %2, %0"
8797 [(set_attr "type" "visl")])
8799 (define_insn "*naddsf3"
8800 [(set (match_operand:SF 0 "register_operand" "=f")
8801 (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8802 (match_operand:SF 2 "register_operand" "f"))))]
8804 "fnadds\t%1, %2, %0"
8805 [(set_attr "type" "fp")])
8807 (define_insn "*nadddf3"
8808 [(set (match_operand:DF 0 "register_operand" "=e")
8809 (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8810 (match_operand:DF 2 "register_operand" "e"))))]
8812 "fnaddd\t%1, %2, %0"
8813 [(set_attr "type" "fp")
8814 (set_attr "fptype" "double")])
8816 (define_insn "*nmulsf3"
8817 [(set (match_operand:SF 0 "register_operand" "=f")
8818 (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8819 (match_operand:SF 2 "register_operand" "f")))]
8821 "fnmuls\t%1, %2, %0"
8822 [(set_attr "type" "fpmul")])
8824 (define_insn "*nmuldf3"
8825 [(set (match_operand:DF 0 "register_operand" "=e")
8826 (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8827 (match_operand:DF 2 "register_operand" "e")))]
8829 "fnmuld\t%1, %2, %0"
8830 [(set_attr "type" "fpmul")
8831 (set_attr "fptype" "double")])
8833 (define_insn "*nmuldf3_extend"
8834 [(set (match_operand:DF 0 "register_operand" "=e")
8835 (mult:DF (neg:DF (float_extend:DF
8836 (match_operand:SF 1 "register_operand" "f")))
8838 (match_operand:SF 2 "register_operand" "f"))))]
8840 "fnsmuld\t%1, %2, %0"
8841 [(set_attr "type" "fpmul")
8842 (set_attr "fptype" "double")])
8844 (define_insn "fhaddsf_vis"
8845 [(set (match_operand:SF 0 "register_operand" "=f")
8846 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8847 (match_operand:SF 2 "register_operand" "f")]
8850 "fhadds\t%1, %2, %0"
8851 [(set_attr "type" "fp")])
8853 (define_insn "fhadddf_vis"
8854 [(set (match_operand:DF 0 "register_operand" "=f")
8855 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8856 (match_operand:DF 2 "register_operand" "f")]
8859 "fhaddd\t%1, %2, %0"
8860 [(set_attr "type" "fp")
8861 (set_attr "fptype" "double")])
8863 (define_insn "fhsubsf_vis"
8864 [(set (match_operand:SF 0 "register_operand" "=f")
8865 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8866 (match_operand:SF 2 "register_operand" "f")]
8869 "fhsubs\t%1, %2, %0"
8870 [(set_attr "type" "fp")])
8872 (define_insn "fhsubdf_vis"
8873 [(set (match_operand:DF 0 "register_operand" "=f")
8874 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8875 (match_operand:DF 2 "register_operand" "f")]
8878 "fhsubd\t%1, %2, %0"
8879 [(set_attr "type" "fp")
8880 (set_attr "fptype" "double")])
8882 (define_insn "fnhaddsf_vis"
8883 [(set (match_operand:SF 0 "register_operand" "=f")
8884 (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8885 (match_operand:SF 2 "register_operand" "f")]
8888 "fnhadds\t%1, %2, %0"
8889 [(set_attr "type" "fp")])
8891 (define_insn "fnhadddf_vis"
8892 [(set (match_operand:DF 0 "register_operand" "=f")
8893 (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8894 (match_operand:DF 2 "register_operand" "f")]
8897 "fnhaddd\t%1, %2, %0"
8898 [(set_attr "type" "fp")
8899 (set_attr "fptype" "double")])
8901 (define_expand "umulxhi_vis"
8902 [(set (match_operand:DI 0 "register_operand" "")
8905 (mult:TI (zero_extend:TI
8906 (match_operand:DI 1 "arith_operand" ""))
8908 (match_operand:DI 2 "arith_operand" "")))
8912 if (! TARGET_ARCH64)
8914 emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8919 (define_insn "*umulxhi_sp64"
8920 [(set (match_operand:DI 0 "register_operand" "=r")
8923 (mult:TI (zero_extend:TI
8924 (match_operand:DI 1 "arith_operand" "%r"))
8926 (match_operand:DI 2 "arith_operand" "rI")))
8928 "TARGET_VIS3 && TARGET_ARCH64"
8929 "umulxhi\t%1, %2, %0"
8930 [(set_attr "type" "imul")])
8932 (define_insn "umulxhi_v8plus"
8933 [(set (match_operand:DI 0 "register_operand" "=r,h")
8936 (mult:TI (zero_extend:TI
8937 (match_operand:DI 1 "arith_operand" "%r,0"))
8939 (match_operand:DI 2 "arith_operand" "rI,rI")))
8941 (clobber (match_scratch:SI 3 "=&h,X"))
8942 (clobber (match_scratch:SI 4 "=&h,X"))]
8943 "TARGET_VIS3 && ! TARGET_ARCH64"
8944 "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8945 [(set_attr "type" "imul")
8946 (set_attr "length" "9,8")])
8948 (define_expand "xmulx_vis"
8949 [(set (match_operand:DI 0 "register_operand" "")
8951 (unspec:TI [(zero_extend:TI
8952 (match_operand:DI 1 "arith_operand" ""))
8954 (match_operand:DI 2 "arith_operand" ""))]
8958 if (! TARGET_ARCH64)
8960 emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8965 (define_insn "*xmulx_sp64"
8966 [(set (match_operand:DI 0 "register_operand" "=r")
8968 (unspec:TI [(zero_extend:TI
8969 (match_operand:DI 1 "arith_operand" "%r"))
8971 (match_operand:DI 2 "arith_operand" "rI"))]
8973 "TARGET_VIS3 && TARGET_ARCH64"
8975 [(set_attr "type" "imul")])
8977 (define_insn "xmulx_v8plus"
8978 [(set (match_operand:DI 0 "register_operand" "=r,h")
8980 (unspec:TI [(zero_extend:TI
8981 (match_operand:DI 1 "arith_operand" "%r,0"))
8983 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8985 (clobber (match_scratch:SI 3 "=&h,X"))
8986 (clobber (match_scratch:SI 4 "=&h,X"))]
8987 "TARGET_VIS3 && ! TARGET_ARCH64"
8988 "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8989 [(set_attr "type" "imul")
8990 (set_attr "length" "9,8")])
8992 (define_expand "xmulxhi_vis"
8993 [(set (match_operand:DI 0 "register_operand" "")
8996 (unspec:TI [(zero_extend:TI
8997 (match_operand:DI 1 "arith_operand" ""))
8999 (match_operand:DI 2 "arith_operand" ""))]
9004 if (! TARGET_ARCH64)
9006 emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
9011 (define_insn "*xmulxhi_sp64"
9012 [(set (match_operand:DI 0 "register_operand" "=r")
9015 (unspec:TI [(zero_extend:TI
9016 (match_operand:DI 1 "arith_operand" "%r"))
9018 (match_operand:DI 2 "arith_operand" "rI"))]
9021 "TARGET_VIS3 && TARGET_ARCH64"
9022 "xmulxhi\t%1, %2, %0"
9023 [(set_attr "type" "imul")])
9025 (define_insn "xmulxhi_v8plus"
9026 [(set (match_operand:DI 0 "register_operand" "=r,h")
9029 (unspec:TI [(zero_extend:TI
9030 (match_operand:DI 1 "arith_operand" "%r,0"))
9032 (match_operand:DI 2 "arith_operand" "rI,rI"))]
9035 (clobber (match_scratch:SI 3 "=&h,X"))
9036 (clobber (match_scratch:SI 4 "=&h,X"))]
9037 "TARGET_VIS3 && !TARGET_ARCH64"
9038 "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
9039 [(set_attr "type" "imul")
9040 (set_attr "length" "9,8")])