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 ;; UltraSPARC-III integer load type.
428 (define_attr "us3load_type" "2cycle,3cycle"
429 (const_string "2cycle"))
431 (define_asm_attributes
432 [(set_attr "length" "2")
433 (set_attr "type" "multi")])
435 ;; Attributes for branch scheduling
436 (define_attr "in_call_delay" "false,true"
437 (symbol_ref "(eligible_for_call_delay (insn)
438 ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)"))
440 (define_attr "in_sibcall_delay" "false,true"
441 (symbol_ref "(eligible_for_sibcall_delay (insn)
442 ? IN_SIBCALL_DELAY_TRUE : IN_SIBCALL_DELAY_FALSE)"))
444 (define_attr "in_return_delay" "false,true"
445 (symbol_ref "(eligible_for_return_delay (insn)
446 ? IN_RETURN_DELAY_TRUE : IN_RETURN_DELAY_FALSE)"))
448 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
449 ;; branches. This would allow us to remove the nop always inserted before
450 ;; a floating point branch.
452 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
453 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
454 ;; This is because doing so will add several pipeline stalls to the path
455 ;; that the load/store did not come from. Unfortunately, there is no way
456 ;; to prevent fill_eager_delay_slots from using load/store without completely
457 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
458 ;; because it prevents us from moving back the final store of inner loops.
460 (define_attr "in_branch_delay" "false,true"
461 (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
462 (const_string "false")
463 (and (eq_attr "fix_ut699" "true") (eq_attr "type" "load,sload"))
464 (const_string "false")
465 (and (eq_attr "fix_ut699" "true")
466 (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts")
467 (eq_attr "fptype" "single")))
468 (const_string "false")
469 (eq_attr "length" "1")
470 (const_string "true")
471 ] (const_string "false")))
473 (define_delay (eq_attr "type" "call")
474 [(eq_attr "in_call_delay" "true") (nil) (nil)])
476 (define_delay (eq_attr "type" "sibcall")
477 [(eq_attr "in_sibcall_delay" "true") (nil) (nil)])
479 (define_delay (eq_attr "type" "return")
480 [(eq_attr "in_return_delay" "true") (nil) (nil)])
482 (define_delay (eq_attr "type" "branch")
483 [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")])
485 (define_delay (eq_attr "type" "uncond_branch")
486 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
489 ;; Include SPARC DFA schedulers
491 (include "cypress.md")
492 (include "supersparc.md")
493 (include "hypersparc.md")
495 (include "sparclet.md")
496 (include "ultra1_2.md")
497 (include "ultra3.md")
498 (include "niagara.md")
499 (include "niagara2.md")
500 (include "niagara4.md")
503 ;; Operand and operator predicates and constraints
505 (include "predicates.md")
506 (include "constraints.md")
509 ;; Compare instructions.
511 ;; These are just the DEFINE_INSNs to match the patterns and the
512 ;; DEFINE_SPLITs for some of the scc insns that actually require
513 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
515 ;; The compare DEFINE_INSNs.
517 (define_insn "*cmpsi_insn"
518 [(set (reg:CC CC_REG)
519 (compare:CC (match_operand:SI 0 "register_operand" "r")
520 (match_operand:SI 1 "arith_operand" "rI")))]
523 [(set_attr "type" "compare")])
525 (define_insn "*cmpdi_sp64"
526 [(set (reg:CCX CC_REG)
527 (compare:CCX (match_operand:DI 0 "register_operand" "r")
528 (match_operand:DI 1 "arith_operand" "rI")))]
531 [(set_attr "type" "compare")])
533 (define_insn "*cmpsf_fpe"
534 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
535 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
536 (match_operand:SF 2 "register_operand" "f")))]
540 return "fcmpes\t%0, %1, %2";
541 return "fcmpes\t%1, %2";
543 [(set_attr "type" "fpcmp")])
545 (define_insn "*cmpdf_fpe"
546 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
547 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
548 (match_operand:DF 2 "register_operand" "e")))]
552 return "fcmped\t%0, %1, %2";
553 return "fcmped\t%1, %2";
555 [(set_attr "type" "fpcmp")
556 (set_attr "fptype" "double")])
558 (define_insn "*cmptf_fpe"
559 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
560 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
561 (match_operand:TF 2 "register_operand" "e")))]
562 "TARGET_FPU && TARGET_HARD_QUAD"
565 return "fcmpeq\t%0, %1, %2";
566 return "fcmpeq\t%1, %2";
568 [(set_attr "type" "fpcmp")])
570 (define_insn "*cmpsf_fp"
571 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
572 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
573 (match_operand:SF 2 "register_operand" "f")))]
577 return "fcmps\t%0, %1, %2";
578 return "fcmps\t%1, %2";
580 [(set_attr "type" "fpcmp")])
582 (define_insn "*cmpdf_fp"
583 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
584 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
585 (match_operand:DF 2 "register_operand" "e")))]
589 return "fcmpd\t%0, %1, %2";
590 return "fcmpd\t%1, %2";
592 [(set_attr "type" "fpcmp")
593 (set_attr "fptype" "double")])
595 (define_insn "*cmptf_fp"
596 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
597 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
598 (match_operand:TF 2 "register_operand" "e")))]
599 "TARGET_FPU && TARGET_HARD_QUAD"
602 return "fcmpq\t%0, %1, %2";
603 return "fcmpq\t%1, %2";
605 [(set_attr "type" "fpcmp")])
607 ;; Next come the scc insns.
609 ;; Note that the boolean result (operand 0) takes on DImode
610 ;; (not SImode) when TARGET_ARCH64.
612 (define_expand "cstoresi4"
613 [(use (match_operator 1 "comparison_operator"
614 [(match_operand:SI 2 "compare_operand" "")
615 (match_operand:SI 3 "arith_operand" "")]))
616 (clobber (match_operand:SI 0 "cstore_result_operand"))]
619 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
620 operands[2] = force_reg (SImode, operands[2]);
621 if (emit_scc_insn (operands)) DONE; else FAIL;
624 (define_expand "cstoredi4"
625 [(use (match_operator 1 "comparison_operator"
626 [(match_operand:DI 2 "compare_operand" "")
627 (match_operand:DI 3 "arith_operand" "")]))
628 (clobber (match_operand:SI 0 "cstore_result_operand"))]
631 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
632 operands[2] = force_reg (DImode, operands[2]);
633 if (emit_scc_insn (operands)) DONE; else FAIL;
636 (define_expand "cstore<F:mode>4"
637 [(use (match_operator 1 "comparison_operator"
638 [(match_operand:F 2 "register_operand" "")
639 (match_operand:F 3 "register_operand" "")]))
640 (clobber (match_operand:SI 0 "cstore_result_operand"))]
642 { if (emit_scc_insn (operands)) DONE; else FAIL; })
646 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
647 ;; generate addcc/subcc instructions.
649 (define_expand "seqsi<P:mode>_special"
651 (xor:SI (match_operand:SI 1 "register_operand" "")
652 (match_operand:SI 2 "register_operand" "")))
653 (parallel [(set (match_operand:P 0 "register_operand" "")
654 (eq:P (match_dup 3) (const_int 0)))
655 (clobber (reg:CC CC_REG))])]
657 { operands[3] = gen_reg_rtx (SImode); })
659 (define_expand "seqdi_special"
661 (xor:DI (match_operand:DI 1 "register_operand" "")
662 (match_operand:DI 2 "register_operand" "")))
663 (set (match_operand:DI 0 "register_operand" "")
664 (eq:DI (match_dup 3) (const_int 0)))]
666 { operands[3] = gen_reg_rtx (DImode); })
668 (define_expand "snesi<P:mode>_special"
670 (xor:SI (match_operand:SI 1 "register_operand" "")
671 (match_operand:SI 2 "register_operand" "")))
672 (parallel [(set (match_operand:P 0 "register_operand" "")
673 (ne:P (match_dup 3) (const_int 0)))
674 (clobber (reg:CC CC_REG))])]
676 { operands[3] = gen_reg_rtx (SImode); })
678 (define_expand "snedi_special"
680 (xor:DI (match_operand:DI 1 "register_operand" "")
681 (match_operand:DI 2 "register_operand" "")))
682 (set (match_operand:DI 0 "register_operand" "")
683 (ne:DI (match_dup 3) (const_int 0)))]
684 "TARGET_ARCH64 && ! TARGET_VIS3"
685 { operands[3] = gen_reg_rtx (DImode); })
687 (define_expand "snedi_special_vis3"
689 (xor:DI (match_operand:DI 1 "register_operand" "")
690 (match_operand:DI 2 "register_operand" "")))
691 (parallel [(set (match_operand:DI 0 "register_operand" "")
692 (ne:DI (match_dup 3) (const_int 0)))
693 (clobber (reg:CCX CC_REG))])]
694 "TARGET_ARCH64 && TARGET_VIS3"
695 { operands[3] = gen_reg_rtx (DImode); })
698 ;; Now the DEFINE_INSNs for the scc cases.
700 ;; The SEQ and SNE patterns are special because they can be done
701 ;; without any branching and do not involve a COMPARE. We want
702 ;; them to always use the splits below so the results can be
705 (define_insn_and_split "*snesi<P:mode>_zero"
706 [(set (match_operand:P 0 "register_operand" "=r")
707 (ne:P (match_operand:SI 1 "register_operand" "r")
709 (clobber (reg:CC CC_REG))]
713 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
715 (set (match_dup 0) (ltu:P (reg:CC CC_REG) (const_int 0)))]
717 [(set_attr "length" "2")])
719 (define_insn_and_split "*neg_snesisi_zero"
720 [(set (match_operand:SI 0 "register_operand" "=r")
721 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
723 (clobber (reg:CC CC_REG))]
727 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
729 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
731 [(set_attr "length" "2")])
733 (define_insn_and_split "*neg_snesidi_zero"
734 [(set (match_operand:DI 0 "register_operand" "=r")
735 (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r")
737 (clobber (reg:CC CC_REG))]
741 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
743 (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG)
746 [(set_attr "length" "2")])
748 (define_insn_and_split "*snedi_zero"
749 [(set (match_operand:DI 0 "register_operand" "=&r")
750 (ne:DI (match_operand:DI 1 "register_operand" "r")
752 "TARGET_ARCH64 && ! TARGET_VIS3"
754 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
755 [(set (match_dup 0) (const_int 0))
756 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
761 [(set_attr "length" "2")])
763 (define_insn_and_split "*snedi_zero_vis3"
764 [(set (match_operand:DI 0 "register_operand" "=r")
765 (ne:DI (match_operand:DI 1 "register_operand" "r")
767 (clobber (reg:CCX CC_REG))]
768 "TARGET_ARCH64 && TARGET_VIS3"
771 [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
773 (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
775 [(set_attr "length" "2")])
777 (define_insn_and_split "*neg_snedi_zero"
778 [(set (match_operand:DI 0 "register_operand" "=&r")
779 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
783 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
784 [(set (match_dup 0) (const_int 0))
785 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
790 [(set_attr "length" "2")])
792 (define_insn_and_split "*snedi_zero_trunc"
793 [(set (match_operand:SI 0 "register_operand" "=&r")
794 (ne:SI (match_operand:DI 1 "register_operand" "r")
796 "TARGET_ARCH64 && ! TARGET_VIS3"
798 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
799 [(set (match_dup 0) (const_int 0))
800 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
805 [(set_attr "length" "2")])
807 (define_insn_and_split "*snedi_zero_trunc_vis3"
808 [(set (match_operand:SI 0 "register_operand" "=r")
809 (ne:SI (match_operand:DI 1 "register_operand" "r")
811 (clobber (reg:CCX CC_REG))]
812 "TARGET_ARCH64 && TARGET_VIS3"
815 [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
817 (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
819 [(set_attr "length" "2")])
821 (define_insn_and_split "*seqsi<P:mode>_zero"
822 [(set (match_operand:P 0 "register_operand" "=r")
823 (eq:P (match_operand:SI 1 "register_operand" "r")
825 (clobber (reg:CC CC_REG))]
829 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
831 (set (match_dup 0) (geu:P (reg:CC CC_REG) (const_int 0)))]
833 [(set_attr "length" "2")])
835 (define_insn_and_split "*neg_seqsisi_zero"
836 [(set (match_operand:SI 0 "register_operand" "=r")
837 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
839 (clobber (reg:CC CC_REG))]
843 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
845 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
847 [(set_attr "length" "2")])
849 (define_insn_and_split "*neg_seqsidi_zero"
850 [(set (match_operand:DI 0 "register_operand" "=r")
851 (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r")
853 (clobber (reg:CC CC_REG))]
857 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
859 (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG)
862 [(set_attr "length" "2")])
864 (define_insn_and_split "*seqdi_zero"
865 [(set (match_operand:DI 0 "register_operand" "=&r")
866 (eq:DI (match_operand:DI 1 "register_operand" "r")
870 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
871 [(set (match_dup 0) (const_int 0))
872 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
877 [(set_attr "length" "2")])
879 (define_insn_and_split "*neg_seqdi_zero"
880 [(set (match_operand:DI 0 "register_operand" "=&r")
881 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
885 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
886 [(set (match_dup 0) (const_int 0))
887 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
892 [(set_attr "length" "2")])
894 (define_insn_and_split "*seqdi_zero_trunc"
895 [(set (match_operand:SI 0 "register_operand" "=&r")
896 (eq:SI (match_operand:DI 1 "register_operand" "r")
900 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
901 [(set (match_dup 0) (const_int 0))
902 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
907 [(set_attr "length" "2")])
909 ;; We can also do (x + (i == 0)) and related, so put them in.
910 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
913 (define_insn_and_split "*x_plus_i_ne_0"
914 [(set (match_operand:SI 0 "register_operand" "=r")
915 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
917 (match_operand:SI 2 "register_operand" "r")))
918 (clobber (reg:CC CC_REG))]
922 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
924 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
927 [(set_attr "length" "2")])
929 (define_insn_and_split "*x_minus_i_ne_0"
930 [(set (match_operand:SI 0 "register_operand" "=r")
931 (minus:SI (match_operand:SI 2 "register_operand" "r")
932 (ne:SI (match_operand:SI 1 "register_operand" "r")
934 (clobber (reg:CC CC_REG))]
938 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
940 (set (match_dup 0) (minus:SI (match_dup 2)
941 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
943 [(set_attr "length" "2")])
945 (define_insn_and_split "*x_plus_i_eq_0"
946 [(set (match_operand:SI 0 "register_operand" "=r")
947 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
949 (match_operand:SI 2 "register_operand" "r")))
950 (clobber (reg:CC CC_REG))]
954 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
956 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
959 [(set_attr "length" "2")])
961 (define_insn_and_split "*x_minus_i_eq_0"
962 [(set (match_operand:SI 0 "register_operand" "=r")
963 (minus:SI (match_operand:SI 2 "register_operand" "r")
964 (eq:SI (match_operand:SI 1 "register_operand" "r")
966 (clobber (reg:CC CC_REG))]
970 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
972 (set (match_dup 0) (minus:SI (match_dup 2)
973 (geu:SI (reg:CC CC_REG) (const_int 0))))]
975 [(set_attr "length" "2")])
977 ;; We can also do GEU and LTU directly, but these operate after a compare.
978 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
981 (define_insn "*sltu<P:mode>_insn"
982 [(set (match_operand:P 0 "register_operand" "=r")
983 (ltu:P (reg:CC CC_REG) (const_int 0)))]
986 [(set_attr "type" "ialuX")])
988 (define_insn "*sltu_insn_vis3"
989 [(set (match_operand:DI 0 "register_operand" "=r")
990 (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
991 "TARGET_ARCH64 && TARGET_VIS3"
992 "addxc\t%%g0, %%g0, %0"
993 [(set_attr "type" "ialuX")])
995 (define_insn "*sltu_insn_vis3_trunc"
996 [(set (match_operand:SI 0 "register_operand" "=r")
997 (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
998 "TARGET_ARCH64 && TARGET_VIS3"
999 "addxc\t%%g0, %%g0, %0"
1000 [(set_attr "type" "ialuX")])
1002 (define_insn "*neg_sltusi_insn"
1003 [(set (match_operand:SI 0 "register_operand" "=r")
1004 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1007 [(set_attr "type" "ialuX")])
1009 (define_insn "*neg_sltudi_insn"
1010 [(set (match_operand:DI 0 "register_operand" "=r")
1011 (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))]
1014 [(set_attr "type" "ialuX")])
1016 (define_insn "*neg_sltu_minus_x"
1017 [(set (match_operand:SI 0 "register_operand" "=r")
1018 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
1019 (match_operand:SI 1 "arith_operand" "rI")))]
1021 "subx\t%%g0, %1, %0"
1022 [(set_attr "type" "ialuX")])
1024 (define_insn "*neg_sltu_plus_x"
1025 [(set (match_operand:SI 0 "register_operand" "=r")
1026 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1027 (match_operand:SI 1 "arith_operand" "rI"))))]
1029 "subx\t%%g0, %1, %0"
1030 [(set_attr "type" "ialuX")])
1032 (define_insn "*sgeu<P:mode>_insn"
1033 [(set (match_operand:P 0 "register_operand" "=r")
1034 (geu:P (reg:CC CC_REG) (const_int 0)))]
1036 "subx\t%%g0, -1, %0"
1037 [(set_attr "type" "ialuX")])
1039 (define_insn "*neg_sgeusi_insn"
1040 [(set (match_operand:SI 0 "register_operand" "=r")
1041 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
1043 "addx\t%%g0, -1, %0"
1044 [(set_attr "type" "ialuX")])
1046 (define_insn "*neg_sgeudi_insn"
1047 [(set (match_operand:DI 0 "register_operand" "=r")
1048 (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))]
1050 "addx\t%%g0, -1, %0"
1051 [(set_attr "type" "ialuX")])
1053 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1054 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1057 (define_insn "*sltu_plus_x"
1058 [(set (match_operand:SI 0 "register_operand" "=r")
1059 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1060 (match_operand:SI 1 "arith_operand" "rI")))]
1062 "addx\t%%g0, %1, %0"
1063 [(set_attr "type" "ialuX")])
1065 (define_insn "*sltu_plus_x_plus_y"
1066 [(set (match_operand:SI 0 "register_operand" "=r")
1067 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1068 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1069 (match_operand:SI 2 "arith_operand" "rI"))))]
1072 [(set_attr "type" "ialuX")])
1074 (define_insn "*x_minus_sltu"
1075 [(set (match_operand:SI 0 "register_operand" "=r")
1076 (minus:SI (match_operand:SI 1 "register_operand" "r")
1077 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1080 [(set_attr "type" "ialuX")])
1082 ;; ??? Combine should canonicalize these next two to the same pattern.
1083 (define_insn "*x_minus_y_minus_sltu"
1084 [(set (match_operand:SI 0 "register_operand" "=r")
1085 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1086 (match_operand:SI 2 "arith_operand" "rI"))
1087 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1090 [(set_attr "type" "ialuX")])
1092 (define_insn "*x_minus_sltu_plus_y"
1093 [(set (match_operand:SI 0 "register_operand" "=r")
1094 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1095 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1096 (match_operand:SI 2 "arith_operand" "rI"))))]
1099 [(set_attr "type" "ialuX")])
1101 (define_insn "*sgeu_plus_x"
1102 [(set (match_operand:SI 0 "register_operand" "=r")
1103 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1104 (match_operand:SI 1 "register_operand" "r")))]
1107 [(set_attr "type" "ialuX")])
1109 (define_insn "*x_minus_sgeu"
1110 [(set (match_operand:SI 0 "register_operand" "=r")
1111 (minus:SI (match_operand:SI 1 "register_operand" "r")
1112 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1115 [(set_attr "type" "ialuX")])
1118 [(set (match_operand:SI 0 "register_operand" "")
1119 (match_operator:SI 2 "noov_compare_operator"
1120 [(match_operand 1 "icc_or_fcc_register_operand" "")
1123 && REGNO (operands[1]) == SPARC_ICC_REG
1124 && (GET_MODE (operands[1]) == CCXmode
1125 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1126 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1127 [(set (match_dup 0) (const_int 0))
1129 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1135 ;; These control RTL generation for conditional jump insns
1137 (define_expand "cbranchcc4"
1139 (if_then_else (match_operator 0 "comparison_operator"
1140 [(match_operand 1 "compare_operand" "")
1141 (match_operand 2 "const_zero_operand" "")])
1142 (label_ref (match_operand 3 "" ""))
1147 (define_expand "cbranchsi4"
1148 [(use (match_operator 0 "comparison_operator"
1149 [(match_operand:SI 1 "compare_operand" "")
1150 (match_operand:SI 2 "arith_operand" "")]))
1151 (use (match_operand 3 ""))]
1154 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1155 operands[1] = force_reg (SImode, operands[1]);
1156 emit_conditional_branch_insn (operands);
1160 (define_expand "cbranchdi4"
1161 [(use (match_operator 0 "comparison_operator"
1162 [(match_operand:DI 1 "compare_operand" "")
1163 (match_operand:DI 2 "arith_operand" "")]))
1164 (use (match_operand 3 ""))]
1167 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1168 operands[1] = force_reg (DImode, operands[1]);
1169 emit_conditional_branch_insn (operands);
1173 (define_expand "cbranch<F:mode>4"
1174 [(use (match_operator 0 "comparison_operator"
1175 [(match_operand:F 1 "register_operand" "")
1176 (match_operand:F 2 "register_operand" "")]))
1177 (use (match_operand 3 ""))]
1179 { emit_conditional_branch_insn (operands); DONE; })
1182 ;; Now match both normal and inverted jump.
1184 ;; XXX fpcmp nop braindamage
1185 (define_insn "*normal_branch"
1187 (if_then_else (match_operator 0 "noov_compare_operator"
1188 [(reg CC_REG) (const_int 0)])
1189 (label_ref (match_operand 1 "" ""))
1193 return output_cbranch (operands[0], operands[1], 1, 0,
1194 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1197 [(set_attr "type" "branch")
1198 (set_attr "branch_type" "icc")])
1200 ;; XXX fpcmp nop braindamage
1201 (define_insn "*inverted_branch"
1203 (if_then_else (match_operator 0 "noov_compare_operator"
1204 [(reg CC_REG) (const_int 0)])
1206 (label_ref (match_operand 1 "" ""))))]
1209 return output_cbranch (operands[0], operands[1], 1, 1,
1210 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1213 [(set_attr "type" "branch")
1214 (set_attr "branch_type" "icc")])
1216 ;; XXX fpcmp nop braindamage
1217 (define_insn "*normal_fp_branch"
1219 (if_then_else (match_operator 1 "comparison_operator"
1220 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1222 (label_ref (match_operand 2 "" ""))
1226 return output_cbranch (operands[1], operands[2], 2, 0,
1227 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1230 [(set_attr "type" "branch")
1231 (set_attr "branch_type" "fcc")])
1233 ;; XXX fpcmp nop braindamage
1234 (define_insn "*inverted_fp_branch"
1236 (if_then_else (match_operator 1 "comparison_operator"
1237 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1240 (label_ref (match_operand 2 "" ""))))]
1243 return output_cbranch (operands[1], operands[2], 2, 1,
1244 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1247 [(set_attr "type" "branch")
1248 (set_attr "branch_type" "fcc")])
1250 ;; XXX fpcmp nop braindamage
1251 (define_insn "*normal_fpe_branch"
1253 (if_then_else (match_operator 1 "comparison_operator"
1254 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1256 (label_ref (match_operand 2 "" ""))
1260 return output_cbranch (operands[1], operands[2], 2, 0,
1261 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1264 [(set_attr "type" "branch")
1265 (set_attr "branch_type" "fcc")])
1267 ;; XXX fpcmp nop braindamage
1268 (define_insn "*inverted_fpe_branch"
1270 (if_then_else (match_operator 1 "comparison_operator"
1271 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1274 (label_ref (match_operand 2 "" ""))))]
1277 return output_cbranch (operands[1], operands[2], 2, 1,
1278 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1281 [(set_attr "type" "branch")
1282 (set_attr "branch_type" "fcc")])
1284 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1285 ;; in the architecture.
1287 (define_insn "*cbcond_sp32"
1289 (if_then_else (match_operator 0 "noov_compare_operator"
1290 [(match_operand:SI 1 "register_operand" "r")
1291 (match_operand:SI 2 "arith5_operand" "rA")])
1292 (label_ref (match_operand 3 "" ""))
1296 return output_cbcond (operands[0], operands[3], insn);
1298 [(set_attr "type" "cbcond")])
1300 (define_insn "*cbcond_sp64"
1302 (if_then_else (match_operator 0 "noov_compare_operator"
1303 [(match_operand:DI 1 "register_operand" "r")
1304 (match_operand:DI 2 "arith5_operand" "rA")])
1305 (label_ref (match_operand 3 "" ""))
1307 "TARGET_ARCH64 && TARGET_CBCOND"
1309 return output_cbcond (operands[0], operands[3], insn);
1311 [(set_attr "type" "cbcond")])
1313 ;; There are no 32 bit brreg insns.
1316 (define_insn "*normal_int_branch_sp64"
1318 (if_then_else (match_operator 0 "v9_register_compare_operator"
1319 [(match_operand:DI 1 "register_operand" "r")
1321 (label_ref (match_operand 2 "" ""))
1325 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1326 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1329 [(set_attr "type" "branch")
1330 (set_attr "branch_type" "reg")])
1333 (define_insn "*inverted_int_branch_sp64"
1335 (if_then_else (match_operator 0 "v9_register_compare_operator"
1336 [(match_operand:DI 1 "register_operand" "r")
1339 (label_ref (match_operand 2 "" ""))))]
1342 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1343 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1346 [(set_attr "type" "branch")
1347 (set_attr "branch_type" "reg")])
1350 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1351 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1352 ;; that adds the PC value at the call point to register #(operand 3).
1354 ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..."
1355 ;; because the RDPC instruction is extremely expensive and incurs a complete
1356 ;; instruction pipeline flush.
1358 (define_insn "load_pcrel_sym<P:mode>"
1359 [(set (match_operand:P 0 "register_operand" "=r")
1360 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1361 (match_operand:P 2 "call_address_operand" "")
1362 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1363 (clobber (reg:P O7_REG))]
1364 "REGNO (operands[0]) == INTVAL (operands[3])"
1366 if (flag_delayed_branch)
1367 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1369 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1371 [(set (attr "type") (const_string "multi"))
1372 (set (attr "length")
1373 (if_then_else (eq_attr "delayed_branch" "true")
1378 ;; Integer move instructions
1380 (define_expand "movqi"
1381 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1382 (match_operand:QI 1 "general_operand" ""))]
1385 if (sparc_expand_move (QImode, operands))
1389 (define_insn "*movqi_insn"
1390 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1391 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1392 "(register_operand (operands[0], QImode)
1393 || register_or_zero_operand (operands[1], QImode))"
1398 [(set_attr "type" "*,load,store")
1399 (set_attr "us3load_type" "*,3cycle,*")])
1401 (define_expand "movhi"
1402 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1403 (match_operand:HI 1 "general_operand" ""))]
1406 if (sparc_expand_move (HImode, operands))
1410 (define_insn "*movhi_insn"
1411 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1412 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1413 "(register_operand (operands[0], HImode)
1414 || register_or_zero_operand (operands[1], HImode))"
1417 sethi\t%%hi(%a1), %0
1420 [(set_attr "type" "*,*,load,store")
1421 (set_attr "us3load_type" "*,*,3cycle,*")])
1423 ;; We always work with constants here.
1424 (define_insn "*movhi_lo_sum"
1425 [(set (match_operand:HI 0 "register_operand" "=r")
1426 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1427 (match_operand:HI 2 "small_int_operand" "I")))]
1431 (define_expand "movsi"
1432 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1433 (match_operand:SI 1 "general_operand" ""))]
1436 if (sparc_expand_move (SImode, operands))
1440 (define_insn "*movsi_insn"
1441 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1442 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1443 "register_operand (operands[0], SImode)
1444 || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1447 sethi\t%%hi(%a1), %0
1457 [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1458 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1460 (define_insn "*movsi_lo_sum"
1461 [(set (match_operand:SI 0 "register_operand" "=r")
1462 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1463 (match_operand:SI 2 "immediate_operand" "in")))]
1465 "or\t%1, %%lo(%a2), %0")
1467 (define_insn "*movsi_high"
1468 [(set (match_operand:SI 0 "register_operand" "=r")
1469 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1471 "sethi\t%%hi(%a1), %0")
1473 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1474 ;; so that CSE won't optimize the address computation away.
1475 (define_insn "movsi_lo_sum_pic"
1476 [(set (match_operand:SI 0 "register_operand" "=r")
1477 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1478 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1481 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1482 return "xor\t%1, %%gdop_lox10(%a2), %0";
1484 return "or\t%1, %%lo(%a2), %0";
1488 (define_insn "movsi_high_pic"
1489 [(set (match_operand:SI 0 "register_operand" "=r")
1490 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1491 "flag_pic && check_pic (1)"
1493 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1494 return "sethi\t%%gdop_hix22(%a1), %0";
1496 return "sethi\t%%hi(%a1), %0";
1500 (define_insn "movsi_pic_gotdata_op"
1501 [(set (match_operand:SI 0 "register_operand" "=r")
1502 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1503 (match_operand:SI 2 "register_operand" "r")
1504 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1505 "flag_pic && check_pic (1)"
1507 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1508 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1510 return "ld\t[%1 + %2], %0";
1513 [(set_attr "type" "load")])
1515 (define_expand "movsi_pic_label_ref"
1516 [(set (match_dup 3) (high:SI
1517 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1518 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1519 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1520 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1521 (set (match_operand:SI 0 "register_operand" "=r")
1522 (minus:SI (match_dup 5) (match_dup 4)))]
1525 crtl->uses_pic_offset_table = 1;
1526 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1527 if (!can_create_pseudo_p ())
1529 operands[3] = operands[0];
1530 operands[4] = operands[0];
1534 operands[3] = gen_reg_rtx (SImode);
1535 operands[4] = gen_reg_rtx (SImode);
1537 operands[5] = pic_offset_table_rtx;
1540 (define_insn "*movsi_high_pic_label_ref"
1541 [(set (match_operand:SI 0 "register_operand" "=r")
1543 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1544 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1546 "sethi\t%%hi(%a2-(%a1-.)), %0")
1548 (define_insn "*movsi_lo_sum_pic_label_ref"
1549 [(set (match_operand:SI 0 "register_operand" "=r")
1550 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1551 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1552 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1554 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1556 ;; Set up the PIC register for VxWorks.
1558 (define_expand "vxworks_load_got"
1560 (high:SI (match_dup 1)))
1562 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1564 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1565 "TARGET_VXWORKS_RTP"
1567 operands[0] = pic_offset_table_rtx;
1568 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1569 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1572 (define_expand "movdi"
1573 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1574 (match_operand:DI 1 "general_operand" ""))]
1577 if (sparc_expand_move (DImode, operands))
1581 ;; Be careful, fmovd does not exist when !v9.
1582 ;; We match MEM moves directly when we have correct even
1583 ;; numbered registers, but fall into splits otherwise.
1584 ;; The constraint ordering here is really important to
1585 ;; avoid insane problems in reload, especially for patterns
1588 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1589 ;; (const_int -5016)))
1593 (define_insn "*movdi_insn_sp32"
1594 [(set (match_operand:DI 0 "nonimmediate_operand"
1595 "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e, r,?*f,?*e,?W,b,b")
1596 (match_operand:DI 1 "input_operand"
1597 " J,J,U,T,r,o,i,r,*f, T, o,*f, *e, *e,?*f, r, W,*e,J,P"))]
1599 && (register_operand (operands[0], DImode)
1600 || register_or_zero_operand (operands[1], DImode))"
1622 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl")
1623 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1624 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1625 (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
1627 (define_insn "*movdi_insn_sp64"
1628 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1629 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,*e, r, *e, W,*e,J,P"))]
1631 && (register_operand (operands[0], DImode)
1632 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1635 sethi\t%%hi(%a1), %0
1645 [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1646 (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1647 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1649 (define_expand "movdi_pic_label_ref"
1650 [(set (match_dup 3) (high:DI
1651 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1652 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1653 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1654 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1655 (set (match_operand:DI 0 "register_operand" "=r")
1656 (minus:DI (match_dup 5) (match_dup 4)))]
1657 "TARGET_ARCH64 && flag_pic"
1659 crtl->uses_pic_offset_table = 1;
1660 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1661 if (!can_create_pseudo_p ())
1663 operands[3] = operands[0];
1664 operands[4] = operands[0];
1668 operands[3] = gen_reg_rtx (DImode);
1669 operands[4] = gen_reg_rtx (DImode);
1671 operands[5] = pic_offset_table_rtx;
1674 (define_insn "*movdi_high_pic_label_ref"
1675 [(set (match_operand:DI 0 "register_operand" "=r")
1677 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1678 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1679 "TARGET_ARCH64 && flag_pic"
1680 "sethi\t%%hi(%a2-(%a1-.)), %0")
1682 (define_insn "*movdi_lo_sum_pic_label_ref"
1683 [(set (match_operand:DI 0 "register_operand" "=r")
1684 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1685 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1686 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1687 "TARGET_ARCH64 && flag_pic"
1688 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1690 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1691 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1693 (define_insn "movdi_lo_sum_pic"
1694 [(set (match_operand:DI 0 "register_operand" "=r")
1695 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1696 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1697 "TARGET_ARCH64 && flag_pic"
1699 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1700 return "xor\t%1, %%gdop_lox10(%a2), %0";
1702 return "or\t%1, %%lo(%a2), %0";
1706 (define_insn "movdi_high_pic"
1707 [(set (match_operand:DI 0 "register_operand" "=r")
1708 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1709 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1711 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1712 return "sethi\t%%gdop_hix22(%a1), %0";
1714 return "sethi\t%%hi(%a1), %0";
1718 (define_insn "movdi_pic_gotdata_op"
1719 [(set (match_operand:DI 0 "register_operand" "=r")
1720 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1721 (match_operand:DI 2 "register_operand" "r")
1722 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1723 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1725 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1726 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1728 return "ldx\t[%1 + %2], %0";
1731 [(set_attr "type" "load")])
1733 (define_insn "*sethi_di_medlow_embmedany_pic"
1734 [(set (match_operand:DI 0 "register_operand" "=r")
1735 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1736 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1737 "sethi\t%%hi(%a1), %0")
1739 (define_insn "*sethi_di_medlow"
1740 [(set (match_operand:DI 0 "register_operand" "=r")
1741 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1742 "TARGET_CM_MEDLOW && check_pic (1)"
1743 "sethi\t%%hi(%a1), %0")
1745 (define_insn "*losum_di_medlow"
1746 [(set (match_operand:DI 0 "register_operand" "=r")
1747 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1748 (match_operand:DI 2 "symbolic_operand" "")))]
1750 "or\t%1, %%lo(%a2), %0")
1752 (define_insn "seth44"
1753 [(set (match_operand:DI 0 "register_operand" "=r")
1754 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1756 "sethi\t%%h44(%a1), %0")
1758 (define_insn "setm44"
1759 [(set (match_operand:DI 0 "register_operand" "=r")
1760 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1761 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1763 "or\t%1, %%m44(%a2), %0")
1765 (define_insn "setl44"
1766 [(set (match_operand:DI 0 "register_operand" "=r")
1767 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1768 (match_operand:DI 2 "symbolic_operand" "")))]
1770 "or\t%1, %%l44(%a2), %0")
1772 (define_insn "sethh"
1773 [(set (match_operand:DI 0 "register_operand" "=r")
1774 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1776 "sethi\t%%hh(%a1), %0")
1778 (define_insn "setlm"
1779 [(set (match_operand:DI 0 "register_operand" "=r")
1780 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1782 "sethi\t%%lm(%a1), %0")
1784 (define_insn "sethm"
1785 [(set (match_operand:DI 0 "register_operand" "=r")
1786 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1787 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1789 "or\t%1, %%hm(%a2), %0")
1791 (define_insn "setlo"
1792 [(set (match_operand:DI 0 "register_operand" "=r")
1793 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1794 (match_operand:DI 2 "symbolic_operand" "")))]
1796 "or\t%1, %%lo(%a2), %0")
1798 (define_insn "embmedany_sethi"
1799 [(set (match_operand:DI 0 "register_operand" "=r")
1800 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1801 "TARGET_CM_EMBMEDANY && check_pic (1)"
1802 "sethi\t%%hi(%a1), %0")
1804 (define_insn "embmedany_losum"
1805 [(set (match_operand:DI 0 "register_operand" "=r")
1806 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1807 (match_operand:DI 2 "data_segment_operand" "")))]
1808 "TARGET_CM_EMBMEDANY"
1809 "add\t%1, %%lo(%a2), %0")
1811 (define_insn "embmedany_brsum"
1812 [(set (match_operand:DI 0 "register_operand" "=r")
1813 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1814 "TARGET_CM_EMBMEDANY"
1817 (define_insn "embmedany_textuhi"
1818 [(set (match_operand:DI 0 "register_operand" "=r")
1819 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1820 "TARGET_CM_EMBMEDANY && check_pic (1)"
1821 "sethi\t%%uhi(%a1), %0")
1823 (define_insn "embmedany_texthi"
1824 [(set (match_operand:DI 0 "register_operand" "=r")
1825 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1826 "TARGET_CM_EMBMEDANY && check_pic (1)"
1827 "sethi\t%%hi(%a1), %0")
1829 (define_insn "embmedany_textulo"
1830 [(set (match_operand:DI 0 "register_operand" "=r")
1831 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1832 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1833 "TARGET_CM_EMBMEDANY"
1834 "or\t%1, %%ulo(%a2), %0")
1836 (define_insn "embmedany_textlo"
1837 [(set (match_operand:DI 0 "register_operand" "=r")
1838 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1839 (match_operand:DI 2 "text_segment_operand" "")))]
1840 "TARGET_CM_EMBMEDANY"
1841 "or\t%1, %%lo(%a2), %0")
1843 ;; Now some patterns to help reload out a bit.
1844 (define_expand "reload_indi"
1845 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1846 (match_operand:DI 1 "immediate_operand" "")
1847 (match_operand:TI 2 "register_operand" "=&r")])]
1849 || TARGET_CM_EMBMEDANY)
1852 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1856 (define_expand "reload_outdi"
1857 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1858 (match_operand:DI 1 "immediate_operand" "")
1859 (match_operand:TI 2 "register_operand" "=&r")])]
1861 || TARGET_CM_EMBMEDANY)
1864 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1868 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1870 [(set (match_operand:DI 0 "register_operand" "")
1871 (match_operand:DI 1 "const_int_operand" ""))]
1873 && ((GET_CODE (operands[0]) == REG
1874 && SPARC_INT_REG_P (REGNO (operands[0])))
1875 || (GET_CODE (operands[0]) == SUBREG
1876 && GET_CODE (SUBREG_REG (operands[0])) == REG
1877 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))
1878 && reload_completed"
1879 [(clobber (const_int 0))]
1881 #if HOST_BITS_PER_WIDE_INT == 32
1882 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1883 (INTVAL (operands[1]) < 0) ?
1886 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1889 unsigned int low, high;
1891 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1892 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1893 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1895 /* Slick... but this trick loses if this subreg constant part
1896 can be done in one insn. */
1898 && ! SPARC_SETHI32_P (high)
1899 && ! SPARC_SIMM13_P (high))
1900 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1901 gen_highpart (SImode, operands[0])));
1903 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1909 [(set (match_operand:DI 0 "register_operand" "")
1910 (match_operand:DI 1 "const_double_operand" ""))]
1914 && ((GET_CODE (operands[0]) == REG
1915 && SPARC_INT_REG_P (REGNO (operands[0])))
1916 || (GET_CODE (operands[0]) == SUBREG
1917 && GET_CODE (SUBREG_REG (operands[0])) == REG
1918 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
1919 [(clobber (const_int 0))]
1921 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1922 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1924 /* Slick... but this trick loses if this subreg constant part
1925 can be done in one insn. */
1926 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1927 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1928 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1930 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1931 gen_highpart (SImode, operands[0])));
1935 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1936 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1942 [(set (match_operand:DI 0 "register_operand" "")
1943 (match_operand:DI 1 "register_operand" ""))]
1947 && sparc_split_regreg_legitimate (operands[0],
1949 [(clobber (const_int 0))]
1951 rtx set_dest = operands[0];
1952 rtx set_src = operands[1];
1956 dest1 = gen_highpart (SImode, set_dest);
1957 dest2 = gen_lowpart (SImode, set_dest);
1958 src1 = gen_highpart (SImode, set_src);
1959 src2 = gen_lowpart (SImode, set_src);
1961 /* Now emit using the real source and destination we found, swapping
1962 the order if we detect overlap. */
1963 if (reg_overlap_mentioned_p (dest1, src2))
1965 emit_insn (gen_movsi (dest2, src2));
1966 emit_insn (gen_movsi (dest1, src1));
1970 emit_insn (gen_movsi (dest1, src1));
1971 emit_insn (gen_movsi (dest2, src2));
1976 ;; Now handle the cases of memory moves from/to non-even
1977 ;; DI mode register pairs.
1979 [(set (match_operand:DI 0 "register_operand" "")
1980 (match_operand:DI 1 "memory_operand" ""))]
1983 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1984 [(clobber (const_int 0))]
1986 rtx word0 = adjust_address (operands[1], SImode, 0);
1987 rtx word1 = adjust_address (operands[1], SImode, 4);
1988 rtx high_part = gen_highpart (SImode, operands[0]);
1989 rtx low_part = gen_lowpart (SImode, operands[0]);
1991 if (reg_overlap_mentioned_p (high_part, word1))
1993 emit_insn (gen_movsi (low_part, word1));
1994 emit_insn (gen_movsi (high_part, word0));
1998 emit_insn (gen_movsi (high_part, word0));
1999 emit_insn (gen_movsi (low_part, word1));
2005 [(set (match_operand:DI 0 "memory_operand" "")
2006 (match_operand:DI 1 "register_operand" ""))]
2009 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2010 [(clobber (const_int 0))]
2012 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2013 gen_highpart (SImode, operands[1])));
2014 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2015 gen_lowpart (SImode, operands[1])));
2020 [(set (match_operand:DI 0 "memory_operand" "")
2021 (match_operand:DI 1 "const_zero_operand" ""))]
2025 && ! mem_min_alignment (operands[0], 8)))
2026 && offsettable_memref_p (operands[0])"
2027 [(clobber (const_int 0))]
2029 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2030 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2034 (define_expand "movti"
2035 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2036 (match_operand:TI 1 "general_operand" ""))]
2039 if (sparc_expand_move (TImode, operands))
2043 ;; We need to prevent reload from splitting TImode moves, because it
2044 ;; might decide to overwrite a pointer with the value it points to.
2045 ;; In that case we have to do the loads in the appropriate order so
2046 ;; that the pointer is not destroyed too early.
2048 (define_insn "*movti_insn_sp64"
2049 [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b")
2050 (match_operand:TI 1 "input_operand" "roJ,rJ, eo, e,J"))]
2052 && ! TARGET_HARD_QUAD
2053 && (register_operand (operands[0], TImode)
2054 || register_or_zero_operand (operands[1], TImode))"
2056 [(set_attr "length" "2,2,2,2,2")
2057 (set_attr "cpu_feature" "*,*,fpu,fpu,vis")])
2059 (define_insn "*movti_insn_sp64_hq"
2060 [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b")
2061 (match_operand:TI 1 "input_operand" "roJ,rJ, e, m, e,J"))]
2064 && (register_operand (operands[0], TImode)
2065 || register_or_zero_operand (operands[1], TImode))"
2073 [(set_attr "type" "*,*,fpmove,fpload,fpstore,*")
2074 (set_attr "length" "2,2,*,*,*,2")])
2076 ;; Now all the splits to handle multi-insn TI mode moves.
2078 [(set (match_operand:TI 0 "register_operand" "")
2079 (match_operand:TI 1 "register_operand" ""))]
2082 && ! TARGET_HARD_QUAD)
2083 || (! fp_register_operand (operands[0], TImode)
2084 && ! fp_register_operand (operands[1], TImode)))"
2085 [(clobber (const_int 0))]
2087 rtx set_dest = operands[0];
2088 rtx set_src = operands[1];
2092 dest1 = gen_highpart (DImode, set_dest);
2093 dest2 = gen_lowpart (DImode, set_dest);
2094 src1 = gen_highpart (DImode, set_src);
2095 src2 = gen_lowpart (DImode, set_src);
2097 /* Now emit using the real source and destination we found, swapping
2098 the order if we detect overlap. */
2099 if (reg_overlap_mentioned_p (dest1, src2))
2101 emit_insn (gen_movdi (dest2, src2));
2102 emit_insn (gen_movdi (dest1, src1));
2106 emit_insn (gen_movdi (dest1, src1));
2107 emit_insn (gen_movdi (dest2, src2));
2113 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2114 (match_operand:TI 1 "const_zero_operand" ""))]
2116 [(clobber (const_int 0))]
2118 rtx set_dest = operands[0];
2121 switch (GET_CODE (set_dest))
2124 dest1 = gen_highpart (DImode, set_dest);
2125 dest2 = gen_lowpart (DImode, set_dest);
2128 dest1 = adjust_address (set_dest, DImode, 0);
2129 dest2 = adjust_address (set_dest, DImode, 8);
2135 emit_insn (gen_movdi (dest1, const0_rtx));
2136 emit_insn (gen_movdi (dest2, const0_rtx));
2141 [(set (match_operand:TI 0 "register_operand" "")
2142 (match_operand:TI 1 "memory_operand" ""))]
2144 && offsettable_memref_p (operands[1])
2145 && (! TARGET_HARD_QUAD
2146 || ! fp_register_operand (operands[0], TImode))"
2147 [(clobber (const_int 0))]
2149 rtx word0 = adjust_address (operands[1], DImode, 0);
2150 rtx word1 = adjust_address (operands[1], DImode, 8);
2151 rtx set_dest, dest1, dest2;
2153 set_dest = operands[0];
2155 dest1 = gen_highpart (DImode, set_dest);
2156 dest2 = gen_lowpart (DImode, set_dest);
2158 /* Now output, ordering such that we don't clobber any registers
2159 mentioned in the address. */
2160 if (reg_overlap_mentioned_p (dest1, word1))
2163 emit_insn (gen_movdi (dest2, word1));
2164 emit_insn (gen_movdi (dest1, word0));
2168 emit_insn (gen_movdi (dest1, word0));
2169 emit_insn (gen_movdi (dest2, word1));
2175 [(set (match_operand:TI 0 "memory_operand" "")
2176 (match_operand:TI 1 "register_operand" ""))]
2178 && offsettable_memref_p (operands[0])
2179 && (! TARGET_HARD_QUAD
2180 || ! fp_register_operand (operands[1], TImode))"
2181 [(clobber (const_int 0))]
2183 rtx set_src = operands[1];
2185 emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0),
2186 gen_highpart (DImode, set_src)));
2187 emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8),
2188 gen_lowpart (DImode, set_src)));
2193 ;; Floating point move instructions
2195 (define_expand "movsf"
2196 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2197 (match_operand:SF 1 "general_operand" ""))]
2200 if (sparc_expand_move (SFmode, operands))
2204 (define_insn "*movsf_insn"
2205 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m, m")
2206 (match_operand:SF 1 "input_operand" "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2207 "(register_operand (operands[0], SFmode)
2208 || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2210 if (GET_CODE (operands[1]) == CONST_DOUBLE
2211 && (which_alternative == 3
2212 || which_alternative == 4
2213 || which_alternative == 5))
2218 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2219 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2220 operands[1] = GEN_INT (i);
2223 switch (which_alternative)
2226 return "fzeros\t%0";
2230 return "fmovs\t%1, %0";
2232 return "mov\t%1, %0";
2234 return "sethi\t%%hi(%a1), %0";
2238 return "movstouw\t%1, %0";
2240 return "movwtos\t%1, %0";
2243 return "ld\t%1, %0";
2246 return "st\t%r1, %0";
2251 [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store")
2252 (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2254 ;; The following 3 patterns build SFmode constants in integer registers.
2256 (define_insn "*movsf_lo_sum"
2257 [(set (match_operand:SF 0 "register_operand" "=r")
2258 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2259 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2265 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2266 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2267 operands[2] = GEN_INT (i);
2268 return "or\t%1, %%lo(%a2), %0";
2271 (define_insn "*movsf_high"
2272 [(set (match_operand:SF 0 "register_operand" "=r")
2273 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2279 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2280 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2281 operands[1] = GEN_INT (i);
2282 return "sethi\t%%hi(%1), %0";
2286 [(set (match_operand:SF 0 "register_operand" "")
2287 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2288 "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2289 [(set (match_dup 0) (high:SF (match_dup 1)))
2290 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2292 (define_expand "movdf"
2293 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2294 (match_operand:DF 1 "general_operand" ""))]
2297 if (sparc_expand_move (DFmode, operands))
2301 (define_insn "*movdf_insn_sp32"
2302 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f, e,T,W,U,T, f, *r, o,o")
2303 (match_operand:DF 1 "input_operand" "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))]
2305 && (register_operand (operands[0], DFmode)
2306 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2323 [(set_attr "type" "visl,visl,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*")
2324 (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2")
2325 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2326 (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")])
2328 (define_insn "*movdf_insn_sp64"
2329 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r")
2330 (match_operand:DF 1 "input_operand" "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2332 && (register_operand (operands[0], DFmode)
2333 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2346 [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*")
2347 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2348 (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2349 (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2351 ;; This pattern builds DFmode constants in integer registers.
2353 [(set (match_operand:DF 0 "register_operand" "")
2354 (match_operand:DF 1 "const_double_operand" ""))]
2355 "REG_P (operands[0])
2356 && SPARC_INT_REG_P (REGNO (operands[0]))
2357 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2358 && reload_completed"
2359 [(clobber (const_int 0))]
2361 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2365 #if HOST_BITS_PER_WIDE_INT == 32
2368 enum machine_mode mode = GET_MODE (operands[1]);
2369 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2370 emit_insn (gen_movdi (operands[0], tem));
2375 enum machine_mode mode = GET_MODE (operands[1]);
2376 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2377 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2379 gcc_assert (GET_CODE (hi) == CONST_INT);
2380 gcc_assert (GET_CODE (lo) == CONST_INT);
2382 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2384 /* Slick... but this trick loses if this subreg constant part
2385 can be done in one insn. */
2387 && ! SPARC_SETHI32_P (INTVAL (hi))
2388 && ! SPARC_SIMM13_P (INTVAL (hi)))
2390 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2391 gen_highpart (SImode, operands[0])));
2395 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2401 ;; Ok, now the splits to handle all the multi insn and
2402 ;; mis-aligned memory address cases.
2403 ;; In these splits please take note that we must be
2404 ;; careful when V9 but not ARCH64 because the integer
2405 ;; register DFmode cases must be handled.
2407 [(set (match_operand:DF 0 "register_operand" "")
2408 (match_operand:DF 1 "register_operand" ""))]
2411 && sparc_split_regreg_legitimate (operands[0],
2413 && reload_completed"
2414 [(clobber (const_int 0))]
2416 rtx set_dest = operands[0];
2417 rtx set_src = operands[1];
2421 dest1 = gen_highpart (SFmode, set_dest);
2422 dest2 = gen_lowpart (SFmode, set_dest);
2423 src1 = gen_highpart (SFmode, set_src);
2424 src2 = gen_lowpart (SFmode, set_src);
2426 /* Now emit using the real source and destination we found, swapping
2427 the order if we detect overlap. */
2428 if (reg_overlap_mentioned_p (dest1, src2))
2430 emit_move_insn_1 (dest2, src2);
2431 emit_move_insn_1 (dest1, src1);
2435 emit_move_insn_1 (dest1, src1);
2436 emit_move_insn_1 (dest2, src2);
2442 [(set (match_operand:DF 0 "register_operand" "")
2443 (match_operand:DF 1 "memory_operand" ""))]
2446 && (((REGNO (operands[0]) % 2) != 0)
2447 || ! mem_min_alignment (operands[1], 8))
2448 && offsettable_memref_p (operands[1])"
2449 [(clobber (const_int 0))]
2453 word0 = adjust_address (operands[1], SFmode, 0);
2454 word1 = adjust_address (operands[1], SFmode, 4);
2456 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2458 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2459 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2463 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2464 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2470 [(set (match_operand:DF 0 "memory_operand" "")
2471 (match_operand:DF 1 "register_operand" ""))]
2474 && (((REGNO (operands[1]) % 2) != 0)
2475 || ! mem_min_alignment (operands[0], 8))
2476 && offsettable_memref_p (operands[0])"
2477 [(clobber (const_int 0))]
2481 word0 = adjust_address (operands[0], SFmode, 0);
2482 word1 = adjust_address (operands[0], SFmode, 4);
2484 emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2485 emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2490 [(set (match_operand:DF 0 "memory_operand" "")
2491 (match_operand:DF 1 "const_zero_operand" ""))]
2495 && ! mem_min_alignment (operands[0], 8)))
2496 && offsettable_memref_p (operands[0])"
2497 [(clobber (const_int 0))]
2501 dest1 = adjust_address (operands[0], SFmode, 0);
2502 dest2 = adjust_address (operands[0], SFmode, 4);
2504 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2505 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2510 [(set (match_operand:DF 0 "register_operand" "")
2511 (match_operand:DF 1 "const_zero_operand" ""))]
2514 && ((GET_CODE (operands[0]) == REG
2515 && SPARC_INT_REG_P (REGNO (operands[0])))
2516 || (GET_CODE (operands[0]) == SUBREG
2517 && GET_CODE (SUBREG_REG (operands[0])) == REG
2518 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2519 [(clobber (const_int 0))]
2521 rtx set_dest = operands[0];
2524 dest1 = gen_highpart (SFmode, set_dest);
2525 dest2 = gen_lowpart (SFmode, set_dest);
2526 emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2527 emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2531 (define_expand "movtf"
2532 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2533 (match_operand:TF 1 "general_operand" ""))]
2536 if (sparc_expand_move (TFmode, operands))
2540 (define_insn "*movtf_insn_sp32"
2541 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,U, r")
2542 (match_operand:TF 1 "input_operand" " G,oe,e,rGU,o,roG"))]
2544 && (register_operand (operands[0], TFmode)
2545 || register_or_zero_operand (operands[1], TFmode))"
2547 [(set_attr "length" "4,4,4,4,4,4")
2548 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")])
2550 (define_insn "*movtf_insn_sp64"
2551 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o, r")
2552 (match_operand:TF 1 "input_operand" "G,oe,e,rG,roG"))]
2554 && ! TARGET_HARD_QUAD
2555 && (register_operand (operands[0], TFmode)
2556 || register_or_zero_operand (operands[1], TFmode))"
2558 [(set_attr "length" "2,2,2,2,2")
2559 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2561 (define_insn "*movtf_insn_sp64_hq"
2562 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o, r")
2563 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2566 && (register_operand (operands[0], TFmode)
2567 || register_or_zero_operand (operands[1], TFmode))"
2575 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2576 (set_attr "length" "2,*,*,*,2,2")])
2578 ;; Now all the splits to handle multi-insn TF mode moves.
2580 [(set (match_operand:TF 0 "register_operand" "")
2581 (match_operand:TF 1 "register_operand" ""))]
2585 && ! TARGET_HARD_QUAD)
2586 || (! fp_register_operand (operands[0], TFmode)
2587 && ! fp_register_operand (operands[1], TFmode)))"
2588 [(clobber (const_int 0))]
2590 rtx set_dest = operands[0];
2591 rtx set_src = operands[1];
2595 dest1 = gen_df_reg (set_dest, 0);
2596 dest2 = gen_df_reg (set_dest, 1);
2597 src1 = gen_df_reg (set_src, 0);
2598 src2 = gen_df_reg (set_src, 1);
2600 /* Now emit using the real source and destination we found, swapping
2601 the order if we detect overlap. */
2602 if (reg_overlap_mentioned_p (dest1, src2))
2604 emit_insn (gen_movdf (dest2, src2));
2605 emit_insn (gen_movdf (dest1, src1));
2609 emit_insn (gen_movdf (dest1, src1));
2610 emit_insn (gen_movdf (dest2, src2));
2616 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2617 (match_operand:TF 1 "const_zero_operand" ""))]
2619 [(clobber (const_int 0))]
2621 rtx set_dest = operands[0];
2624 switch (GET_CODE (set_dest))
2627 dest1 = gen_df_reg (set_dest, 0);
2628 dest2 = gen_df_reg (set_dest, 1);
2631 dest1 = adjust_address (set_dest, DFmode, 0);
2632 dest2 = adjust_address (set_dest, DFmode, 8);
2638 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2639 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2644 [(set (match_operand:TF 0 "register_operand" "")
2645 (match_operand:TF 1 "memory_operand" ""))]
2647 && offsettable_memref_p (operands[1])
2649 || ! TARGET_HARD_QUAD
2650 || ! fp_register_operand (operands[0], TFmode)))"
2651 [(clobber (const_int 0))]
2653 rtx word0 = adjust_address (operands[1], DFmode, 0);
2654 rtx word1 = adjust_address (operands[1], DFmode, 8);
2655 rtx set_dest, dest1, dest2;
2657 set_dest = operands[0];
2659 dest1 = gen_df_reg (set_dest, 0);
2660 dest2 = gen_df_reg (set_dest, 1);
2662 /* Now output, ordering such that we don't clobber any registers
2663 mentioned in the address. */
2664 if (reg_overlap_mentioned_p (dest1, word1))
2667 emit_insn (gen_movdf (dest2, word1));
2668 emit_insn (gen_movdf (dest1, word0));
2672 emit_insn (gen_movdf (dest1, word0));
2673 emit_insn (gen_movdf (dest2, word1));
2679 [(set (match_operand:TF 0 "memory_operand" "")
2680 (match_operand:TF 1 "register_operand" ""))]
2682 && offsettable_memref_p (operands[0])
2684 || ! TARGET_HARD_QUAD
2685 || ! fp_register_operand (operands[1], TFmode)))"
2686 [(clobber (const_int 0))]
2688 rtx set_src = operands[1];
2690 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2691 gen_df_reg (set_src, 0)));
2692 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2693 gen_df_reg (set_src, 1)));
2698 ;; SPARC-V9 conditional move instructions
2700 ;; We can handle larger constants here for some flavors, but for now we keep
2701 ;; it simple and only allow those constants supported by all flavors.
2702 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2703 ;; 3 contains the constant if one is present, but we handle either for
2704 ;; generality (sparc.c puts a constant in operand 2).
2706 ;; Our instruction patterns, on the other hand, canonicalize such that
2707 ;; operand 3 must be the set destination.
2709 (define_expand "mov<I:mode>cc"
2710 [(set (match_operand:I 0 "register_operand" "")
2711 (if_then_else:I (match_operand 1 "comparison_operator" "")
2712 (match_operand:I 2 "arith10_operand" "")
2713 (match_operand:I 3 "arith10_operand" "")))]
2714 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2716 if (! sparc_expand_conditional_move (<I:MODE>mode, operands))
2721 (define_expand "mov<F:mode>cc"
2722 [(set (match_operand:F 0 "register_operand" "")
2723 (if_then_else:F (match_operand 1 "comparison_operator" "")
2724 (match_operand:F 2 "register_operand" "")
2725 (match_operand:F 3 "register_operand" "")))]
2726 "TARGET_V9 && TARGET_FPU"
2728 if (! sparc_expand_conditional_move (<F:MODE>mode, operands))
2733 ;; Conditional move define_insns
2735 (define_insn "*mov<I:mode>_cc_v9"
2736 [(set (match_operand:I 0 "register_operand" "=r")
2737 (if_then_else:I (match_operator 1 "comparison_operator"
2738 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2740 (match_operand:I 3 "arith11_operand" "rL")
2741 (match_operand:I 4 "register_operand" "0")))]
2742 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2743 "mov%C1\t%x2, %3, %0"
2744 [(set_attr "type" "cmove")])
2746 (define_insn "*mov<I:mode>_cc_reg_sp64"
2747 [(set (match_operand:I 0 "register_operand" "=r")
2748 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2749 [(match_operand:DI 2 "register_operand" "r")
2751 (match_operand:I 3 "arith10_operand" "rM")
2752 (match_operand:I 4 "register_operand" "0")))]
2754 "movr%D1\t%2, %r3, %0"
2755 [(set_attr "type" "cmove")])
2757 (define_insn "*movsf_cc_v9"
2758 [(set (match_operand:SF 0 "register_operand" "=f")
2759 (if_then_else:SF (match_operator 1 "comparison_operator"
2760 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2762 (match_operand:SF 3 "register_operand" "f")
2763 (match_operand:SF 4 "register_operand" "0")))]
2764 "TARGET_V9 && TARGET_FPU"
2765 "fmovs%C1\t%x2, %3, %0"
2766 [(set_attr "type" "fpcmove")])
2768 (define_insn "*movsf_cc_reg_sp64"
2769 [(set (match_operand:SF 0 "register_operand" "=f")
2770 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2771 [(match_operand:DI 2 "register_operand" "r")
2773 (match_operand:SF 3 "register_operand" "f")
2774 (match_operand:SF 4 "register_operand" "0")))]
2775 "TARGET_ARCH64 && TARGET_FPU"
2776 "fmovrs%D1\t%2, %3, %0"
2777 [(set_attr "type" "fpcrmove")])
2779 ;; Named because invoked by movtf_cc_v9
2780 (define_insn "movdf_cc_v9"
2781 [(set (match_operand:DF 0 "register_operand" "=e")
2782 (if_then_else:DF (match_operator 1 "comparison_operator"
2783 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2785 (match_operand:DF 3 "register_operand" "e")
2786 (match_operand:DF 4 "register_operand" "0")))]
2787 "TARGET_V9 && TARGET_FPU"
2788 "fmovd%C1\t%x2, %3, %0"
2789 [(set_attr "type" "fpcmove")
2790 (set_attr "fptype" "double")])
2792 ;; Named because invoked by movtf_cc_reg_sp64
2793 (define_insn "movdf_cc_reg_sp64"
2794 [(set (match_operand:DF 0 "register_operand" "=e")
2795 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2796 [(match_operand:DI 2 "register_operand" "r")
2798 (match_operand:DF 3 "register_operand" "e")
2799 (match_operand:DF 4 "register_operand" "0")))]
2800 "TARGET_ARCH64 && TARGET_FPU"
2801 "fmovrd%D1\t%2, %3, %0"
2802 [(set_attr "type" "fpcrmove")
2803 (set_attr "fptype" "double")])
2805 (define_insn "*movtf_cc_hq_v9"
2806 [(set (match_operand:TF 0 "register_operand" "=e")
2807 (if_then_else:TF (match_operator 1 "comparison_operator"
2808 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2810 (match_operand:TF 3 "register_operand" "e")
2811 (match_operand:TF 4 "register_operand" "0")))]
2812 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2813 "fmovq%C1\t%x2, %3, %0"
2814 [(set_attr "type" "fpcmove")])
2816 (define_insn "*movtf_cc_reg_hq_sp64"
2817 [(set (match_operand:TF 0 "register_operand" "=e")
2818 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2819 [(match_operand:DI 2 "register_operand" "r")
2821 (match_operand:TF 3 "register_operand" "e")
2822 (match_operand:TF 4 "register_operand" "0")))]
2823 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2824 "fmovrq%D1\t%2, %3, %0"
2825 [(set_attr "type" "fpcrmove")])
2827 (define_insn_and_split "*movtf_cc_v9"
2828 [(set (match_operand:TF 0 "register_operand" "=e")
2829 (if_then_else:TF (match_operator 1 "comparison_operator"
2830 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2832 (match_operand:TF 3 "register_operand" "e")
2833 (match_operand:TF 4 "register_operand" "0")))]
2834 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2836 "&& reload_completed"
2837 [(clobber (const_int 0))]
2839 rtx set_dest = operands[0];
2840 rtx set_srca = operands[3];
2844 dest1 = gen_df_reg (set_dest, 0);
2845 dest2 = gen_df_reg (set_dest, 1);
2846 srca1 = gen_df_reg (set_srca, 0);
2847 srca2 = gen_df_reg (set_srca, 1);
2849 if (reg_overlap_mentioned_p (dest1, srca2))
2851 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2852 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2856 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2857 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2861 [(set_attr "length" "2")])
2863 (define_insn_and_split "*movtf_cc_reg_sp64"
2864 [(set (match_operand:TF 0 "register_operand" "=e")
2865 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2866 [(match_operand:DI 2 "register_operand" "r")
2868 (match_operand:TF 3 "register_operand" "e")
2869 (match_operand:TF 4 "register_operand" "0")))]
2870 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2872 "&& reload_completed"
2873 [(clobber (const_int 0))]
2875 rtx set_dest = operands[0];
2876 rtx set_srca = operands[3];
2880 dest1 = gen_df_reg (set_dest, 0);
2881 dest2 = gen_df_reg (set_dest, 1);
2882 srca1 = gen_df_reg (set_srca, 0);
2883 srca2 = gen_df_reg (set_srca, 1);
2885 if (reg_overlap_mentioned_p (dest1, srca2))
2887 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2888 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2892 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2893 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2897 [(set_attr "length" "2")])
2900 ;; Zero-extension instructions
2902 ;; These patterns originally accepted general_operands, however, slightly
2903 ;; better code is generated by only accepting register_operands, and then
2904 ;; letting combine generate the ldu[hb] insns.
2906 (define_expand "zero_extendhisi2"
2907 [(set (match_operand:SI 0 "register_operand" "")
2908 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2911 rtx temp = gen_reg_rtx (SImode);
2912 rtx shift_16 = GEN_INT (16);
2913 int op1_subbyte = 0;
2915 if (GET_CODE (operand1) == SUBREG)
2917 op1_subbyte = SUBREG_BYTE (operand1);
2918 op1_subbyte /= GET_MODE_SIZE (SImode);
2919 op1_subbyte *= GET_MODE_SIZE (SImode);
2920 operand1 = XEXP (operand1, 0);
2923 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2925 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2929 (define_insn "*zero_extendhisi2_insn"
2930 [(set (match_operand:SI 0 "register_operand" "=r")
2931 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2934 [(set_attr "type" "load")
2935 (set_attr "us3load_type" "3cycle")])
2937 (define_expand "zero_extendqihi2"
2938 [(set (match_operand:HI 0 "register_operand" "")
2939 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2943 (define_insn "*zero_extendqihi2_insn"
2944 [(set (match_operand:HI 0 "register_operand" "=r,r")
2945 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2946 "GET_CODE (operands[1]) != CONST_INT"
2950 [(set_attr "type" "*,load")
2951 (set_attr "us3load_type" "*,3cycle")])
2953 (define_expand "zero_extendqisi2"
2954 [(set (match_operand:SI 0 "register_operand" "")
2955 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2959 (define_insn "*zero_extendqisi2_insn"
2960 [(set (match_operand:SI 0 "register_operand" "=r,r")
2961 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2962 "GET_CODE (operands[1]) != CONST_INT"
2966 [(set_attr "type" "*,load")
2967 (set_attr "us3load_type" "*,3cycle")])
2969 (define_expand "zero_extendqidi2"
2970 [(set (match_operand:DI 0 "register_operand" "")
2971 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2975 (define_insn "*zero_extendqidi2_insn"
2976 [(set (match_operand:DI 0 "register_operand" "=r,r")
2977 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2978 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2982 [(set_attr "type" "*,load")
2983 (set_attr "us3load_type" "*,3cycle")])
2985 (define_expand "zero_extendhidi2"
2986 [(set (match_operand:DI 0 "register_operand" "")
2987 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2990 rtx temp = gen_reg_rtx (DImode);
2991 rtx shift_48 = GEN_INT (48);
2992 int op1_subbyte = 0;
2994 if (GET_CODE (operand1) == SUBREG)
2996 op1_subbyte = SUBREG_BYTE (operand1);
2997 op1_subbyte /= GET_MODE_SIZE (DImode);
2998 op1_subbyte *= GET_MODE_SIZE (DImode);
2999 operand1 = XEXP (operand1, 0);
3002 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3004 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3008 (define_insn "*zero_extendhidi2_insn"
3009 [(set (match_operand:DI 0 "register_operand" "=r")
3010 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3013 [(set_attr "type" "load")
3014 (set_attr "us3load_type" "3cycle")])
3016 ;; ??? Write truncdisi pattern using sra?
3018 (define_expand "zero_extendsidi2"
3019 [(set (match_operand:DI 0 "register_operand" "")
3020 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3024 (define_insn "*zero_extendsidi2_insn_sp64"
3025 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3026 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3028 && GET_CODE (operands[1]) != CONST_INT"
3033 [(set_attr "type" "shift,load,*")
3034 (set_attr "cpu_feature" "*,*,vis3")])
3036 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3037 [(set (match_operand:DI 0 "register_operand" "=r")
3038 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3041 "&& reload_completed"
3042 [(set (match_dup 2) (match_dup 3))
3043 (set (match_dup 4) (match_dup 5))]
3047 dest1 = gen_highpart (SImode, operands[0]);
3048 dest2 = gen_lowpart (SImode, operands[0]);
3050 /* Swap the order in case of overlap. */
3051 if (REGNO (dest1) == REGNO (operands[1]))
3053 operands[2] = dest2;
3054 operands[3] = operands[1];
3055 operands[4] = dest1;
3056 operands[5] = const0_rtx;
3060 operands[2] = dest1;
3061 operands[3] = const0_rtx;
3062 operands[4] = dest2;
3063 operands[5] = operands[1];
3066 [(set_attr "length" "2")])
3068 ;; Simplify comparisons of extended values.
3070 (define_insn "*cmp_zero_extendqisi2"
3071 [(set (reg:CC CC_REG)
3072 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3075 "andcc\t%0, 0xff, %%g0"
3076 [(set_attr "type" "compare")])
3078 (define_insn "*cmp_zero_qi"
3079 [(set (reg:CC CC_REG)
3080 (compare:CC (match_operand:QI 0 "register_operand" "r")
3083 "andcc\t%0, 0xff, %%g0"
3084 [(set_attr "type" "compare")])
3086 (define_insn "*cmp_zero_extendqisi2_set"
3087 [(set (reg:CC CC_REG)
3088 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3090 (set (match_operand:SI 0 "register_operand" "=r")
3091 (zero_extend:SI (match_dup 1)))]
3093 "andcc\t%1, 0xff, %0"
3094 [(set_attr "type" "compare")])
3096 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3097 [(set (reg:CC CC_REG)
3098 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3101 (set (match_operand:SI 0 "register_operand" "=r")
3102 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3104 "andcc\t%1, 0xff, %0"
3105 [(set_attr "type" "compare")])
3107 (define_insn "*cmp_zero_extendqidi2"
3108 [(set (reg:CCX CC_REG)
3109 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3112 "andcc\t%0, 0xff, %%g0"
3113 [(set_attr "type" "compare")])
3115 (define_insn "*cmp_zero_qi_sp64"
3116 [(set (reg:CCX CC_REG)
3117 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3120 "andcc\t%0, 0xff, %%g0"
3121 [(set_attr "type" "compare")])
3123 (define_insn "*cmp_zero_extendqidi2_set"
3124 [(set (reg:CCX CC_REG)
3125 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3127 (set (match_operand:DI 0 "register_operand" "=r")
3128 (zero_extend:DI (match_dup 1)))]
3130 "andcc\t%1, 0xff, %0"
3131 [(set_attr "type" "compare")])
3133 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3134 [(set (reg:CCX CC_REG)
3135 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3138 (set (match_operand:DI 0 "register_operand" "=r")
3139 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3141 "andcc\t%1, 0xff, %0"
3142 [(set_attr "type" "compare")])
3144 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3146 (define_insn "*cmp_siqi_trunc"
3147 [(set (reg:CC CC_REG)
3148 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3151 "andcc\t%0, 0xff, %%g0"
3152 [(set_attr "type" "compare")])
3154 (define_insn "*cmp_siqi_trunc_set"
3155 [(set (reg:CC CC_REG)
3156 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3158 (set (match_operand:QI 0 "register_operand" "=r")
3159 (subreg:QI (match_dup 1) 3))]
3161 "andcc\t%1, 0xff, %0"
3162 [(set_attr "type" "compare")])
3164 (define_insn "*cmp_diqi_trunc"
3165 [(set (reg:CC CC_REG)
3166 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3169 "andcc\t%0, 0xff, %%g0"
3170 [(set_attr "type" "compare")])
3172 (define_insn "*cmp_diqi_trunc_set"
3173 [(set (reg:CC CC_REG)
3174 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3176 (set (match_operand:QI 0 "register_operand" "=r")
3177 (subreg:QI (match_dup 1) 7))]
3179 "andcc\t%1, 0xff, %0"
3180 [(set_attr "type" "compare")])
3183 ;; Sign-extension instructions
3185 ;; These patterns originally accepted general_operands, however, slightly
3186 ;; better code is generated by only accepting register_operands, and then
3187 ;; letting combine generate the lds[hb] insns.
3189 (define_expand "extendhisi2"
3190 [(set (match_operand:SI 0 "register_operand" "")
3191 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3194 rtx temp = gen_reg_rtx (SImode);
3195 rtx shift_16 = GEN_INT (16);
3196 int op1_subbyte = 0;
3198 if (GET_CODE (operand1) == SUBREG)
3200 op1_subbyte = SUBREG_BYTE (operand1);
3201 op1_subbyte /= GET_MODE_SIZE (SImode);
3202 op1_subbyte *= GET_MODE_SIZE (SImode);
3203 operand1 = XEXP (operand1, 0);
3206 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3208 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3212 (define_insn "*sign_extendhisi2_insn"
3213 [(set (match_operand:SI 0 "register_operand" "=r")
3214 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3217 [(set_attr "type" "sload")
3218 (set_attr "us3load_type" "3cycle")])
3220 (define_expand "extendqihi2"
3221 [(set (match_operand:HI 0 "register_operand" "")
3222 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3225 rtx temp = gen_reg_rtx (SImode);
3226 rtx shift_24 = GEN_INT (24);
3227 int op1_subbyte = 0;
3228 int op0_subbyte = 0;
3230 if (GET_CODE (operand1) == SUBREG)
3232 op1_subbyte = SUBREG_BYTE (operand1);
3233 op1_subbyte /= GET_MODE_SIZE (SImode);
3234 op1_subbyte *= GET_MODE_SIZE (SImode);
3235 operand1 = XEXP (operand1, 0);
3237 if (GET_CODE (operand0) == SUBREG)
3239 op0_subbyte = SUBREG_BYTE (operand0);
3240 op0_subbyte /= GET_MODE_SIZE (SImode);
3241 op0_subbyte *= GET_MODE_SIZE (SImode);
3242 operand0 = XEXP (operand0, 0);
3244 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3246 if (GET_MODE (operand0) != SImode)
3247 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3248 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3252 (define_insn "*sign_extendqihi2_insn"
3253 [(set (match_operand:HI 0 "register_operand" "=r")
3254 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3257 [(set_attr "type" "sload")
3258 (set_attr "us3load_type" "3cycle")])
3260 (define_expand "extendqisi2"
3261 [(set (match_operand:SI 0 "register_operand" "")
3262 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3265 rtx temp = gen_reg_rtx (SImode);
3266 rtx shift_24 = GEN_INT (24);
3267 int op1_subbyte = 0;
3269 if (GET_CODE (operand1) == SUBREG)
3271 op1_subbyte = SUBREG_BYTE (operand1);
3272 op1_subbyte /= GET_MODE_SIZE (SImode);
3273 op1_subbyte *= GET_MODE_SIZE (SImode);
3274 operand1 = XEXP (operand1, 0);
3277 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3279 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3283 (define_insn "*sign_extendqisi2_insn"
3284 [(set (match_operand:SI 0 "register_operand" "=r")
3285 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3288 [(set_attr "type" "sload")
3289 (set_attr "us3load_type" "3cycle")])
3291 (define_expand "extendqidi2"
3292 [(set (match_operand:DI 0 "register_operand" "")
3293 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3296 rtx temp = gen_reg_rtx (DImode);
3297 rtx shift_56 = GEN_INT (56);
3298 int op1_subbyte = 0;
3300 if (GET_CODE (operand1) == SUBREG)
3302 op1_subbyte = SUBREG_BYTE (operand1);
3303 op1_subbyte /= GET_MODE_SIZE (DImode);
3304 op1_subbyte *= GET_MODE_SIZE (DImode);
3305 operand1 = XEXP (operand1, 0);
3308 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3310 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3314 (define_insn "*sign_extendqidi2_insn"
3315 [(set (match_operand:DI 0 "register_operand" "=r")
3316 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3319 [(set_attr "type" "sload")
3320 (set_attr "us3load_type" "3cycle")])
3322 (define_expand "extendhidi2"
3323 [(set (match_operand:DI 0 "register_operand" "")
3324 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3327 rtx temp = gen_reg_rtx (DImode);
3328 rtx shift_48 = GEN_INT (48);
3329 int op1_subbyte = 0;
3331 if (GET_CODE (operand1) == SUBREG)
3333 op1_subbyte = SUBREG_BYTE (operand1);
3334 op1_subbyte /= GET_MODE_SIZE (DImode);
3335 op1_subbyte *= GET_MODE_SIZE (DImode);
3336 operand1 = XEXP (operand1, 0);
3339 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3341 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3345 (define_insn "*sign_extendhidi2_insn"
3346 [(set (match_operand:DI 0 "register_operand" "=r")
3347 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3350 [(set_attr "type" "sload")
3351 (set_attr "us3load_type" "3cycle")])
3353 (define_expand "extendsidi2"
3354 [(set (match_operand:DI 0 "register_operand" "")
3355 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3359 (define_insn "*sign_extendsidi2_insn"
3360 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3361 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3367 [(set_attr "type" "shift,sload,*")
3368 (set_attr "us3load_type" "*,3cycle,*")
3369 (set_attr "cpu_feature" "*,*,vis3")])
3372 ;; Special pattern for optimizing bit-field compares. This is needed
3373 ;; because combine uses this as a canonical form.
3375 (define_insn "*cmp_zero_extract"
3376 [(set (reg:CC CC_REG)
3378 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3379 (match_operand:SI 1 "small_int_operand" "I")
3380 (match_operand:SI 2 "small_int_operand" "I"))
3382 "INTVAL (operands[2]) > 19"
3384 int len = INTVAL (operands[1]);
3385 int pos = 32 - INTVAL (operands[2]) - len;
3386 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3387 operands[1] = GEN_INT (mask);
3388 return "andcc\t%0, %1, %%g0";
3390 [(set_attr "type" "compare")])
3392 (define_insn "*cmp_zero_extract_sp64"
3393 [(set (reg:CCX CC_REG)
3395 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3396 (match_operand:SI 1 "small_int_operand" "I")
3397 (match_operand:SI 2 "small_int_operand" "I"))
3399 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3401 int len = INTVAL (operands[1]);
3402 int pos = 64 - INTVAL (operands[2]) - len;
3403 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3404 operands[1] = GEN_INT (mask);
3405 return "andcc\t%0, %1, %%g0";
3407 [(set_attr "type" "compare")])
3410 ;; Conversions between float, double and long double.
3412 (define_insn "extendsfdf2"
3413 [(set (match_operand:DF 0 "register_operand" "=e")
3415 (match_operand:SF 1 "register_operand" "f")))]
3418 [(set_attr "type" "fp")
3419 (set_attr "fptype" "double")])
3421 (define_expand "extendsftf2"
3422 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3424 (match_operand:SF 1 "register_operand" "")))]
3425 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3426 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3428 (define_insn "*extendsftf2_hq"
3429 [(set (match_operand:TF 0 "register_operand" "=e")
3431 (match_operand:SF 1 "register_operand" "f")))]
3432 "TARGET_FPU && TARGET_HARD_QUAD"
3434 [(set_attr "type" "fp")])
3436 (define_expand "extenddftf2"
3437 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3439 (match_operand:DF 1 "register_operand" "")))]
3440 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3441 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3443 (define_insn "*extenddftf2_hq"
3444 [(set (match_operand:TF 0 "register_operand" "=e")
3446 (match_operand:DF 1 "register_operand" "e")))]
3447 "TARGET_FPU && TARGET_HARD_QUAD"
3449 [(set_attr "type" "fp")])
3451 (define_insn "truncdfsf2"
3452 [(set (match_operand:SF 0 "register_operand" "=f")
3454 (match_operand:DF 1 "register_operand" "e")))]
3457 [(set_attr "type" "fp")
3458 (set_attr "fptype" "double")])
3460 (define_expand "trunctfsf2"
3461 [(set (match_operand:SF 0 "register_operand" "")
3463 (match_operand:TF 1 "general_operand" "")))]
3464 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3465 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3467 (define_insn "*trunctfsf2_hq"
3468 [(set (match_operand:SF 0 "register_operand" "=f")
3470 (match_operand:TF 1 "register_operand" "e")))]
3471 "TARGET_FPU && TARGET_HARD_QUAD"
3473 [(set_attr "type" "fp")])
3475 (define_expand "trunctfdf2"
3476 [(set (match_operand:DF 0 "register_operand" "")
3478 (match_operand:TF 1 "general_operand" "")))]
3479 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3480 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3482 (define_insn "*trunctfdf2_hq"
3483 [(set (match_operand:DF 0 "register_operand" "=e")
3485 (match_operand:TF 1 "register_operand" "e")))]
3486 "TARGET_FPU && TARGET_HARD_QUAD"
3488 [(set_attr "type" "fp")])
3491 ;; Conversion between fixed point and floating point.
3493 (define_insn "floatsisf2"
3494 [(set (match_operand:SF 0 "register_operand" "=f")
3495 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3498 [(set_attr "type" "fp")
3499 (set_attr "fptype" "double")])
3501 (define_insn "floatsidf2"
3502 [(set (match_operand:DF 0 "register_operand" "=e")
3503 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3506 [(set_attr "type" "fp")
3507 (set_attr "fptype" "double")])
3509 (define_expand "floatsitf2"
3510 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3511 (float:TF (match_operand:SI 1 "register_operand" "")))]
3512 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3513 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3515 (define_insn "*floatsitf2_hq"
3516 [(set (match_operand:TF 0 "register_operand" "=e")
3517 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3518 "TARGET_FPU && TARGET_HARD_QUAD"
3520 [(set_attr "type" "fp")])
3522 (define_expand "floatunssitf2"
3523 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3524 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3525 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3526 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3528 ;; Now the same for 64 bit sources.
3530 (define_insn "floatdisf2"
3531 [(set (match_operand:SF 0 "register_operand" "=f")
3532 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3533 "TARGET_V9 && TARGET_FPU"
3535 [(set_attr "type" "fp")
3536 (set_attr "fptype" "double")])
3538 (define_expand "floatunsdisf2"
3539 [(use (match_operand:SF 0 "register_operand" ""))
3540 (use (match_operand:DI 1 "general_operand" ""))]
3541 "TARGET_ARCH64 && TARGET_FPU"
3542 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3544 (define_insn "floatdidf2"
3545 [(set (match_operand:DF 0 "register_operand" "=e")
3546 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3547 "TARGET_V9 && TARGET_FPU"
3549 [(set_attr "type" "fp")
3550 (set_attr "fptype" "double")])
3552 (define_expand "floatunsdidf2"
3553 [(use (match_operand:DF 0 "register_operand" ""))
3554 (use (match_operand:DI 1 "general_operand" ""))]
3555 "TARGET_ARCH64 && TARGET_FPU"
3556 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3558 (define_expand "floatditf2"
3559 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3560 (float:TF (match_operand:DI 1 "register_operand" "")))]
3561 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3562 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3564 (define_insn "*floatditf2_hq"
3565 [(set (match_operand:TF 0 "register_operand" "=e")
3566 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3567 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3569 [(set_attr "type" "fp")])
3571 (define_expand "floatunsditf2"
3572 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3573 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3574 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3575 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3577 ;; Convert a float to an actual integer.
3578 ;; Truncation is performed as part of the conversion.
3580 (define_insn "fix_truncsfsi2"
3581 [(set (match_operand:SI 0 "register_operand" "=f")
3582 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3585 [(set_attr "type" "fp")
3586 (set_attr "fptype" "double")])
3588 (define_insn "fix_truncdfsi2"
3589 [(set (match_operand:SI 0 "register_operand" "=f")
3590 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3593 [(set_attr "type" "fp")
3594 (set_attr "fptype" "double")])
3596 (define_expand "fix_trunctfsi2"
3597 [(set (match_operand:SI 0 "register_operand" "")
3598 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3599 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3600 "emit_tfmode_cvt (FIX, operands); DONE;")
3602 (define_insn "*fix_trunctfsi2_hq"
3603 [(set (match_operand:SI 0 "register_operand" "=f")
3604 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3605 "TARGET_FPU && TARGET_HARD_QUAD"
3607 [(set_attr "type" "fp")])
3609 (define_expand "fixuns_trunctfsi2"
3610 [(set (match_operand:SI 0 "register_operand" "")
3611 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3612 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3613 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3615 ;; Now the same, for V9 targets
3617 (define_insn "fix_truncsfdi2"
3618 [(set (match_operand:DI 0 "register_operand" "=e")
3619 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3620 "TARGET_V9 && TARGET_FPU"
3622 [(set_attr "type" "fp")
3623 (set_attr "fptype" "double")])
3625 (define_expand "fixuns_truncsfdi2"
3626 [(use (match_operand:DI 0 "register_operand" ""))
3627 (use (match_operand:SF 1 "general_operand" ""))]
3628 "TARGET_ARCH64 && TARGET_FPU"
3629 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3631 (define_insn "fix_truncdfdi2"
3632 [(set (match_operand:DI 0 "register_operand" "=e")
3633 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3634 "TARGET_V9 && TARGET_FPU"
3636 [(set_attr "type" "fp")
3637 (set_attr "fptype" "double")])
3639 (define_expand "fixuns_truncdfdi2"
3640 [(use (match_operand:DI 0 "register_operand" ""))
3641 (use (match_operand:DF 1 "general_operand" ""))]
3642 "TARGET_ARCH64 && TARGET_FPU"
3643 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3645 (define_expand "fix_trunctfdi2"
3646 [(set (match_operand:DI 0 "register_operand" "")
3647 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3648 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3649 "emit_tfmode_cvt (FIX, operands); DONE;")
3651 (define_insn "*fix_trunctfdi2_hq"
3652 [(set (match_operand:DI 0 "register_operand" "=e")
3653 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3654 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3656 [(set_attr "type" "fp")])
3658 (define_expand "fixuns_trunctfdi2"
3659 [(set (match_operand:DI 0 "register_operand" "")
3660 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3661 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3662 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3665 ;; Integer addition/subtraction instructions.
3667 (define_expand "adddi3"
3668 [(set (match_operand:DI 0 "register_operand" "")
3669 (plus:DI (match_operand:DI 1 "register_operand" "")
3670 (match_operand:DI 2 "arith_double_add_operand" "")))]
3673 if (! TARGET_ARCH64)
3675 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3676 gen_rtx_SET (VOIDmode, operands[0],
3677 gen_rtx_PLUS (DImode, operands[1],
3679 gen_rtx_CLOBBER (VOIDmode,
3680 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3685 (define_insn_and_split "*adddi3_insn_sp32"
3686 [(set (match_operand:DI 0 "register_operand" "=&r")
3687 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3688 (match_operand:DI 2 "arith_double_operand" "rHI")))
3689 (clobber (reg:CC CC_REG))]
3692 "&& reload_completed"
3693 [(parallel [(set (reg:CC_NOOV CC_REG)
3694 (compare:CC_NOOV (plus:SI (match_dup 4)
3698 (plus:SI (match_dup 4) (match_dup 5)))])
3700 (plus:SI (plus:SI (match_dup 7)
3702 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3704 operands[3] = gen_lowpart (SImode, operands[0]);
3705 operands[4] = gen_lowpart (SImode, operands[1]);
3706 operands[5] = gen_lowpart (SImode, operands[2]);
3707 operands[6] = gen_highpart (SImode, operands[0]);
3708 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3709 #if HOST_BITS_PER_WIDE_INT == 32
3710 if (GET_CODE (operands[2]) == CONST_INT)
3712 if (INTVAL (operands[2]) < 0)
3713 operands[8] = constm1_rtx;
3715 operands[8] = const0_rtx;
3719 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3721 [(set_attr "length" "2")])
3723 ;; LTU here means "carry set"
3725 [(set (match_operand:SI 0 "register_operand" "=r")
3726 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3727 (match_operand:SI 2 "arith_operand" "rI"))
3728 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3731 [(set_attr "type" "ialuX")])
3733 (define_insn "addxc"
3734 [(set (match_operand:DI 0 "register_operand" "=r")
3735 (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
3736 (match_operand:DI 2 "register_or_zero_operand" "rJ"))
3737 (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3738 "TARGET_ARCH64 && TARGET_VIS3"
3739 "addxc\t%r1, %r2, %0"
3740 [(set_attr "type" "ialuX")])
3742 (define_insn_and_split "*addx_extend_sp32"
3743 [(set (match_operand:DI 0 "register_operand" "=r")
3744 (zero_extend:DI (plus:SI (plus:SI
3745 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3746 (match_operand:SI 2 "arith_operand" "rI"))
3747 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3750 "&& reload_completed"
3751 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3752 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3753 (set (match_dup 4) (const_int 0))]
3754 "operands[3] = gen_lowpart (SImode, operands[0]);
3755 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3756 [(set_attr "length" "2")])
3758 (define_insn "*addx_extend_sp64"
3759 [(set (match_operand:DI 0 "register_operand" "=r")
3760 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3761 (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3762 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3764 "addx\t%r1, %r2, %0"
3765 [(set_attr "type" "ialuX")])
3767 (define_insn "*addxc_trunc_sp64_vis3"
3768 [(set (match_operand:SI 0 "register_operand" "=r")
3769 (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3770 (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3771 (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3772 "TARGET_ARCH64 && TARGET_VIS3"
3773 "addxc\t%r1, %r2, %0"
3774 [(set_attr "type" "ialuX")])
3776 (define_insn_and_split "*adddi3_extend_sp32"
3777 [(set (match_operand:DI 0 "register_operand" "=r")
3778 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3779 (match_operand:DI 2 "register_operand" "r")))
3780 (clobber (reg:CC CC_REG))]
3783 "&& reload_completed"
3784 [(parallel [(set (reg:CC_NOOV CC_REG)
3785 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3787 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3789 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3790 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3791 "operands[3] = gen_lowpart (SImode, operands[2]);
3792 operands[4] = gen_highpart (SImode, operands[2]);
3793 operands[5] = gen_lowpart (SImode, operands[0]);
3794 operands[6] = gen_highpart (SImode, operands[0]);"
3795 [(set_attr "length" "2")])
3797 (define_insn "*adddi3_sp64"
3798 [(set (match_operand:DI 0 "register_operand" "=r,r")
3799 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3800 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3806 (define_insn "addsi3"
3807 [(set (match_operand:SI 0 "register_operand" "=r,r")
3808 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3809 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3814 [(set_attr "type" "*,*")
3815 (set_attr "fptype" "*,*")])
3817 (define_insn "*cmp_cc_plus"
3818 [(set (reg:CC_NOOV CC_REG)
3819 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3820 (match_operand:SI 1 "arith_operand" "rI"))
3823 "addcc\t%0, %1, %%g0"
3824 [(set_attr "type" "compare")])
3826 (define_insn "*cmp_ccx_plus"
3827 [(set (reg:CCX_NOOV CC_REG)
3828 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3829 (match_operand:DI 1 "arith_operand" "rI"))
3832 "addcc\t%0, %1, %%g0"
3833 [(set_attr "type" "compare")])
3835 (define_insn "*cmp_cc_plus_set"
3836 [(set (reg:CC_NOOV CC_REG)
3837 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3838 (match_operand:SI 2 "arith_operand" "rI"))
3840 (set (match_operand:SI 0 "register_operand" "=r")
3841 (plus:SI (match_dup 1) (match_dup 2)))]
3844 [(set_attr "type" "compare")])
3846 (define_insn "*cmp_ccx_plus_set"
3847 [(set (reg:CCX_NOOV CC_REG)
3848 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3849 (match_operand:DI 2 "arith_operand" "rI"))
3851 (set (match_operand:DI 0 "register_operand" "=r")
3852 (plus:DI (match_dup 1) (match_dup 2)))]
3855 [(set_attr "type" "compare")])
3857 (define_expand "subdi3"
3858 [(set (match_operand:DI 0 "register_operand" "")
3859 (minus:DI (match_operand:DI 1 "register_operand" "")
3860 (match_operand:DI 2 "arith_double_add_operand" "")))]
3863 if (! TARGET_ARCH64)
3865 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3866 gen_rtx_SET (VOIDmode, operands[0],
3867 gen_rtx_MINUS (DImode, operands[1],
3869 gen_rtx_CLOBBER (VOIDmode,
3870 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3875 (define_insn_and_split "*subdi3_insn_sp32"
3876 [(set (match_operand:DI 0 "register_operand" "=r")
3877 (minus:DI (match_operand:DI 1 "register_operand" "r")
3878 (match_operand:DI 2 "arith_double_operand" "rHI")))
3879 (clobber (reg:CC CC_REG))]
3882 "&& reload_completed"
3883 [(parallel [(set (reg:CC_NOOV CC_REG)
3884 (compare:CC_NOOV (minus:SI (match_dup 4)
3888 (minus:SI (match_dup 4) (match_dup 5)))])
3890 (minus:SI (minus:SI (match_dup 7)
3892 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3894 operands[3] = gen_lowpart (SImode, operands[0]);
3895 operands[4] = gen_lowpart (SImode, operands[1]);
3896 operands[5] = gen_lowpart (SImode, operands[2]);
3897 operands[6] = gen_highpart (SImode, operands[0]);
3898 operands[7] = gen_highpart (SImode, operands[1]);
3899 #if HOST_BITS_PER_WIDE_INT == 32
3900 if (GET_CODE (operands[2]) == CONST_INT)
3902 if (INTVAL (operands[2]) < 0)
3903 operands[8] = constm1_rtx;
3905 operands[8] = const0_rtx;
3909 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3911 [(set_attr "length" "2")])
3913 ;; LTU here means "carry set"
3915 [(set (match_operand:SI 0 "register_operand" "=r")
3916 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3917 (match_operand:SI 2 "arith_operand" "rI"))
3918 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3921 [(set_attr "type" "ialuX")])
3923 (define_insn "*subx_extend_sp64"
3924 [(set (match_operand:DI 0 "register_operand" "=r")
3925 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3926 (match_operand:SI 2 "arith_operand" "rI"))
3927 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3930 [(set_attr "type" "ialuX")])
3932 (define_insn_and_split "*subx_extend"
3933 [(set (match_operand:DI 0 "register_operand" "=r")
3934 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3935 (match_operand:SI 2 "arith_operand" "rI"))
3936 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3939 "&& reload_completed"
3940 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3941 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3942 (set (match_dup 4) (const_int 0))]
3943 "operands[3] = gen_lowpart (SImode, operands[0]);
3944 operands[4] = gen_highpart (SImode, operands[0]);"
3945 [(set_attr "length" "2")])
3947 (define_insn_and_split "*subdi3_extend_sp32"
3948 [(set (match_operand:DI 0 "register_operand" "=r")
3949 (minus:DI (match_operand:DI 1 "register_operand" "r")
3950 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3951 (clobber (reg:CC CC_REG))]
3954 "&& reload_completed"
3955 [(parallel [(set (reg:CC_NOOV CC_REG)
3956 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3958 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3960 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3961 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3962 "operands[3] = gen_lowpart (SImode, operands[1]);
3963 operands[4] = gen_highpart (SImode, operands[1]);
3964 operands[5] = gen_lowpart (SImode, operands[0]);
3965 operands[6] = gen_highpart (SImode, operands[0]);"
3966 [(set_attr "length" "2")])
3968 (define_insn "*subdi3_sp64"
3969 [(set (match_operand:DI 0 "register_operand" "=r,r")
3970 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3971 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3977 (define_insn "subsi3"
3978 [(set (match_operand:SI 0 "register_operand" "=r,r")
3979 (minus:SI (match_operand:SI 1 "register_operand" "r,r")
3980 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3985 [(set_attr "type" "*,*")
3986 (set_attr "fptype" "*,*")])
3988 (define_insn "*cmp_minus_cc"
3989 [(set (reg:CC_NOOV CC_REG)
3990 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3991 (match_operand:SI 1 "arith_operand" "rI"))
3994 "subcc\t%r0, %1, %%g0"
3995 [(set_attr "type" "compare")])
3997 (define_insn "*cmp_minus_ccx"
3998 [(set (reg:CCX_NOOV CC_REG)
3999 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4000 (match_operand:DI 1 "arith_operand" "rI"))
4003 "subcc\t%0, %1, %%g0"
4004 [(set_attr "type" "compare")])
4006 (define_insn "cmp_minus_cc_set"
4007 [(set (reg:CC_NOOV CC_REG)
4008 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4009 (match_operand:SI 2 "arith_operand" "rI"))
4011 (set (match_operand:SI 0 "register_operand" "=r")
4012 (minus:SI (match_dup 1) (match_dup 2)))]
4014 "subcc\t%r1, %2, %0"
4015 [(set_attr "type" "compare")])
4017 (define_insn "*cmp_minus_ccx_set"
4018 [(set (reg:CCX_NOOV CC_REG)
4019 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4020 (match_operand:DI 2 "arith_operand" "rI"))
4022 (set (match_operand:DI 0 "register_operand" "=r")
4023 (minus:DI (match_dup 1) (match_dup 2)))]
4026 [(set_attr "type" "compare")])
4029 ;; Integer multiply/divide instructions.
4031 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4032 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4034 (define_insn "mulsi3"
4035 [(set (match_operand:SI 0 "register_operand" "=r")
4036 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4037 (match_operand:SI 2 "arith_operand" "rI")))]
4040 [(set_attr "type" "imul")])
4042 (define_expand "muldi3"
4043 [(set (match_operand:DI 0 "register_operand" "")
4044 (mult:DI (match_operand:DI 1 "arith_operand" "")
4045 (match_operand:DI 2 "arith_operand" "")))]
4046 "TARGET_ARCH64 || TARGET_V8PLUS"
4050 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4055 (define_insn "*muldi3_sp64"
4056 [(set (match_operand:DI 0 "register_operand" "=r")
4057 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4058 (match_operand:DI 2 "arith_operand" "rI")))]
4061 [(set_attr "type" "imul")])
4063 ;; V8plus wide multiply.
4065 (define_insn "muldi3_v8plus"
4066 [(set (match_operand:DI 0 "register_operand" "=r,h")
4067 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4068 (match_operand:DI 2 "arith_operand" "rI,rI")))
4069 (clobber (match_scratch:SI 3 "=&h,X"))
4070 (clobber (match_scratch:SI 4 "=&h,X"))]
4072 "* return output_v8plus_mult (insn, operands, \"mulx\");"
4073 [(set_attr "type" "multi")
4074 (set_attr "length" "9,8")])
4076 (define_insn "*cmp_mul_set"
4077 [(set (reg:CC CC_REG)
4078 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4079 (match_operand:SI 2 "arith_operand" "rI"))
4081 (set (match_operand:SI 0 "register_operand" "=r")
4082 (mult:SI (match_dup 1) (match_dup 2)))]
4083 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4084 "smulcc\t%1, %2, %0"
4085 [(set_attr "type" "imul")])
4087 (define_expand "mulsidi3"
4088 [(set (match_operand:DI 0 "register_operand" "")
4089 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4090 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4093 if (CONSTANT_P (operands[2]))
4096 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4098 else if (TARGET_ARCH32)
4099 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4102 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4108 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4113 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4114 ;; registers can hold 64-bit values in the V8plus environment.
4116 (define_insn "mulsidi3_v8plus"
4117 [(set (match_operand:DI 0 "register_operand" "=h,r")
4118 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4119 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4120 (clobber (match_scratch:SI 3 "=X,&h"))]
4123 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4124 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4125 [(set_attr "type" "multi")
4126 (set_attr "length" "2,3")])
4129 (define_insn "const_mulsidi3_v8plus"
4130 [(set (match_operand:DI 0 "register_operand" "=h,r")
4131 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4132 (match_operand:DI 2 "small_int_operand" "I,I")))
4133 (clobber (match_scratch:SI 3 "=X,&h"))]
4136 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4137 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4138 [(set_attr "type" "multi")
4139 (set_attr "length" "2,3")])
4142 (define_insn "*mulsidi3_sp32"
4143 [(set (match_operand:DI 0 "register_operand" "=r")
4144 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4145 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4148 return TARGET_SPARCLET
4149 ? "smuld\t%1, %2, %L0"
4150 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4153 (if_then_else (eq_attr "isa" "sparclet")
4154 (const_string "imul") (const_string "multi")))
4155 (set (attr "length")
4156 (if_then_else (eq_attr "isa" "sparclet")
4157 (const_int 1) (const_int 2)))])
4159 (define_insn "*mulsidi3_sp64"
4160 [(set (match_operand:DI 0 "register_operand" "=r")
4161 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4162 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4163 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4165 [(set_attr "type" "imul")])
4167 ;; Extra pattern, because sign_extend of a constant isn't valid.
4170 (define_insn "const_mulsidi3_sp32"
4171 [(set (match_operand:DI 0 "register_operand" "=r")
4172 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4173 (match_operand:DI 2 "small_int_operand" "I")))]
4176 return TARGET_SPARCLET
4177 ? "smuld\t%1, %2, %L0"
4178 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4181 (if_then_else (eq_attr "isa" "sparclet")
4182 (const_string "imul") (const_string "multi")))
4183 (set (attr "length")
4184 (if_then_else (eq_attr "isa" "sparclet")
4185 (const_int 1) (const_int 2)))])
4187 (define_insn "const_mulsidi3_sp64"
4188 [(set (match_operand:DI 0 "register_operand" "=r")
4189 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4190 (match_operand:DI 2 "small_int_operand" "I")))]
4191 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4193 [(set_attr "type" "imul")])
4195 (define_expand "smulsi3_highpart"
4196 [(set (match_operand:SI 0 "register_operand" "")
4198 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4199 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4201 "TARGET_HARD_MUL && TARGET_ARCH32"
4203 if (CONSTANT_P (operands[2]))
4207 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4213 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4218 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4219 operands[2], GEN_INT (32)));
4225 (define_insn "smulsi3_highpart_v8plus"
4226 [(set (match_operand:SI 0 "register_operand" "=h,r")
4228 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4229 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4230 (match_operand:SI 3 "small_int_operand" "I,I"))))
4231 (clobber (match_scratch:SI 4 "=X,&h"))]
4234 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4235 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4236 [(set_attr "type" "multi")
4237 (set_attr "length" "2")])
4239 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4242 [(set (match_operand:SI 0 "register_operand" "=h,r")
4245 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4246 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4247 (match_operand:SI 3 "small_int_operand" "I,I"))
4249 (clobber (match_scratch:SI 4 "=X,&h"))]
4252 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4253 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4254 [(set_attr "type" "multi")
4255 (set_attr "length" "2")])
4258 (define_insn "const_smulsi3_highpart_v8plus"
4259 [(set (match_operand:SI 0 "register_operand" "=h,r")
4261 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4262 (match_operand:DI 2 "small_int_operand" "I,I"))
4263 (match_operand:SI 3 "small_int_operand" "I,I"))))
4264 (clobber (match_scratch:SI 4 "=X,&h"))]
4267 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4268 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4269 [(set_attr "type" "multi")
4270 (set_attr "length" "2")])
4273 (define_insn "*smulsi3_highpart_sp32"
4274 [(set (match_operand:SI 0 "register_operand" "=r")
4276 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4277 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4280 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4281 [(set_attr "type" "multi")
4282 (set_attr "length" "2")])
4285 (define_insn "const_smulsi3_highpart"
4286 [(set (match_operand:SI 0 "register_operand" "=r")
4288 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4289 (match_operand:DI 2 "small_int_operand" "i"))
4292 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4293 [(set_attr "type" "multi")
4294 (set_attr "length" "2")])
4296 (define_expand "umulsidi3"
4297 [(set (match_operand:DI 0 "register_operand" "")
4298 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4299 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4302 if (CONSTANT_P (operands[2]))
4305 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4307 else if (TARGET_ARCH32)
4308 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4311 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4317 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4323 (define_insn "umulsidi3_v8plus"
4324 [(set (match_operand:DI 0 "register_operand" "=h,r")
4325 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4326 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4327 (clobber (match_scratch:SI 3 "=X,&h"))]
4330 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4331 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4332 [(set_attr "type" "multi")
4333 (set_attr "length" "2,3")])
4336 (define_insn "*umulsidi3_sp32"
4337 [(set (match_operand:DI 0 "register_operand" "=r")
4338 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4339 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4342 return TARGET_SPARCLET
4343 ? "umuld\t%1, %2, %L0"
4344 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4347 (if_then_else (eq_attr "isa" "sparclet")
4348 (const_string "imul") (const_string "multi")))
4349 (set (attr "length")
4350 (if_then_else (eq_attr "isa" "sparclet")
4351 (const_int 1) (const_int 2)))])
4353 (define_insn "*umulsidi3_sp64"
4354 [(set (match_operand:DI 0 "register_operand" "=r")
4355 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4356 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4357 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4359 [(set_attr "type" "imul")])
4361 ;; Extra pattern, because sign_extend of a constant isn't valid.
4364 (define_insn "const_umulsidi3_sp32"
4365 [(set (match_operand:DI 0 "register_operand" "=r")
4366 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4367 (match_operand:DI 2 "uns_small_int_operand" "")))]
4370 return TARGET_SPARCLET
4371 ? "umuld\t%1, %s2, %L0"
4372 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4375 (if_then_else (eq_attr "isa" "sparclet")
4376 (const_string "imul") (const_string "multi")))
4377 (set (attr "length")
4378 (if_then_else (eq_attr "isa" "sparclet")
4379 (const_int 1) (const_int 2)))])
4381 (define_insn "const_umulsidi3_sp64"
4382 [(set (match_operand:DI 0 "register_operand" "=r")
4383 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4384 (match_operand:DI 2 "uns_small_int_operand" "")))]
4385 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4387 [(set_attr "type" "imul")])
4390 (define_insn "const_umulsidi3_v8plus"
4391 [(set (match_operand:DI 0 "register_operand" "=h,r")
4392 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4393 (match_operand:DI 2 "uns_small_int_operand" "")))
4394 (clobber (match_scratch:SI 3 "=X,h"))]
4397 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4398 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4399 [(set_attr "type" "multi")
4400 (set_attr "length" "2,3")])
4402 (define_expand "umulsi3_highpart"
4403 [(set (match_operand:SI 0 "register_operand" "")
4405 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4406 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4408 "TARGET_HARD_MUL && TARGET_ARCH32"
4410 if (CONSTANT_P (operands[2]))
4414 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4420 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4425 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4426 operands[2], GEN_INT (32)));
4432 (define_insn "umulsi3_highpart_v8plus"
4433 [(set (match_operand:SI 0 "register_operand" "=h,r")
4435 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4436 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4437 (match_operand:SI 3 "small_int_operand" "I,I"))))
4438 (clobber (match_scratch:SI 4 "=X,h"))]
4441 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4442 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4443 [(set_attr "type" "multi")
4444 (set_attr "length" "2")])
4447 (define_insn "const_umulsi3_highpart_v8plus"
4448 [(set (match_operand:SI 0 "register_operand" "=h,r")
4450 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4451 (match_operand:DI 2 "uns_small_int_operand" ""))
4452 (match_operand:SI 3 "small_int_operand" "I,I"))))
4453 (clobber (match_scratch:SI 4 "=X,h"))]
4456 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4457 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4458 [(set_attr "type" "multi")
4459 (set_attr "length" "2")])
4462 (define_insn "*umulsi3_highpart_sp32"
4463 [(set (match_operand:SI 0 "register_operand" "=r")
4465 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4466 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4469 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4470 [(set_attr "type" "multi")
4471 (set_attr "length" "2")])
4474 (define_insn "const_umulsi3_highpart"
4475 [(set (match_operand:SI 0 "register_operand" "=r")
4477 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4478 (match_operand:DI 2 "uns_small_int_operand" ""))
4481 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4482 [(set_attr "type" "multi")
4483 (set_attr "length" "2")])
4485 (define_expand "divsi3"
4486 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4487 (div:SI (match_operand:SI 1 "register_operand" "")
4488 (match_operand:SI 2 "input_operand" "")))
4489 (clobber (match_scratch:SI 3 ""))])]
4490 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4494 operands[3] = gen_reg_rtx(SImode);
4495 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4496 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4502 ;; The V8 architecture specifies that there must be at least 3 instructions
4503 ;; between a write to the Y register and a use of it for correct results.
4504 ;; We try to fill one of them with a simple constant or a memory load.
4506 (define_insn "divsi3_sp32"
4507 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4508 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4509 (match_operand:SI 2 "input_operand" "rI,K,m")))
4510 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4511 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4513 output_asm_insn ("sra\t%1, 31, %3", operands);
4514 output_asm_insn ("wr\t%3, 0, %%y", operands);
4516 switch (which_alternative)
4520 return "sdiv\t%1, %2, %0";
4522 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4525 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4527 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4530 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4532 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4537 [(set_attr "type" "multi")
4538 (set (attr "length")
4539 (if_then_else (eq_attr "isa" "v9")
4540 (const_int 4) (const_int 6)))])
4542 (define_insn "divsi3_sp64"
4543 [(set (match_operand:SI 0 "register_operand" "=r")
4544 (div:SI (match_operand:SI 1 "register_operand" "r")
4545 (match_operand:SI 2 "input_operand" "rI")))
4546 (use (match_operand:SI 3 "register_operand" "r"))]
4547 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4548 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4549 [(set_attr "type" "multi")
4550 (set_attr "length" "2")])
4552 (define_insn "divdi3"
4553 [(set (match_operand:DI 0 "register_operand" "=r")
4554 (div:DI (match_operand:DI 1 "register_operand" "r")
4555 (match_operand:DI 2 "arith_operand" "rI")))]
4558 [(set_attr "type" "idiv")])
4560 (define_insn "*cmp_sdiv_cc_set"
4561 [(set (reg:CC CC_REG)
4562 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4563 (match_operand:SI 2 "arith_operand" "rI"))
4565 (set (match_operand:SI 0 "register_operand" "=r")
4566 (div:SI (match_dup 1) (match_dup 2)))
4567 (clobber (match_scratch:SI 3 "=&r"))]
4568 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4570 output_asm_insn ("sra\t%1, 31, %3", operands);
4571 output_asm_insn ("wr\t%3, 0, %%y", operands);
4574 return "sdivcc\t%1, %2, %0";
4576 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4578 [(set_attr "type" "multi")
4579 (set (attr "length")
4580 (if_then_else (eq_attr "isa" "v9")
4581 (const_int 3) (const_int 6)))])
4584 (define_expand "udivsi3"
4585 [(set (match_operand:SI 0 "register_operand" "")
4586 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4587 (match_operand:SI 2 "input_operand" "")))]
4588 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4591 ;; The V8 architecture specifies that there must be at least 3 instructions
4592 ;; between a write to the Y register and a use of it for correct results.
4593 ;; We try to fill one of them with a simple constant or a memory load.
4595 (define_insn "udivsi3_sp32"
4596 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4597 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4598 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4599 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4601 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4603 switch (which_alternative)
4607 return "udiv\t%1, %2, %0";
4609 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4612 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4614 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4617 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4619 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4622 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4624 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4629 [(set_attr "type" "multi")
4630 (set (attr "length")
4631 (if_then_else (eq_attr "isa" "v9")
4632 (const_int 3) (const_int 5)))])
4634 (define_insn "udivsi3_sp64"
4635 [(set (match_operand:SI 0 "register_operand" "=r")
4636 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4637 (match_operand:SI 2 "input_operand" "rI")))]
4638 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4639 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4640 [(set_attr "type" "multi")
4641 (set_attr "length" "2")])
4643 (define_insn "udivdi3"
4644 [(set (match_operand:DI 0 "register_operand" "=r")
4645 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4646 (match_operand:DI 2 "arith_operand" "rI")))]
4649 [(set_attr "type" "idiv")])
4651 (define_insn "*cmp_udiv_cc_set"
4652 [(set (reg:CC CC_REG)
4653 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4654 (match_operand:SI 2 "arith_operand" "rI"))
4656 (set (match_operand:SI 0 "register_operand" "=r")
4657 (udiv:SI (match_dup 1) (match_dup 2)))]
4658 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4660 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4663 return "udivcc\t%1, %2, %0";
4665 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4667 [(set_attr "type" "multi")
4668 (set (attr "length")
4669 (if_then_else (eq_attr "isa" "v9")
4670 (const_int 2) (const_int 5)))])
4672 ; sparclet multiply/accumulate insns
4674 (define_insn "*smacsi"
4675 [(set (match_operand:SI 0 "register_operand" "=r")
4676 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4677 (match_operand:SI 2 "arith_operand" "rI"))
4678 (match_operand:SI 3 "register_operand" "0")))]
4681 [(set_attr "type" "imul")])
4683 (define_insn "*smacdi"
4684 [(set (match_operand:DI 0 "register_operand" "=r")
4685 (plus:DI (mult:DI (sign_extend:DI
4686 (match_operand:SI 1 "register_operand" "%r"))
4688 (match_operand:SI 2 "register_operand" "r")))
4689 (match_operand:DI 3 "register_operand" "0")))]
4691 "smacd\t%1, %2, %L0"
4692 [(set_attr "type" "imul")])
4694 (define_insn "*umacdi"
4695 [(set (match_operand:DI 0 "register_operand" "=r")
4696 (plus:DI (mult:DI (zero_extend:DI
4697 (match_operand:SI 1 "register_operand" "%r"))
4699 (match_operand:SI 2 "register_operand" "r")))
4700 (match_operand:DI 3 "register_operand" "0")))]
4702 "umacd\t%1, %2, %L0"
4703 [(set_attr "type" "imul")])
4706 ;; Boolean instructions.
4708 ;; We define DImode `and' so with DImode `not' we can get
4709 ;; DImode `andn'. Other combinations are possible.
4711 (define_expand "anddi3"
4712 [(set (match_operand:DI 0 "register_operand" "")
4713 (and:DI (match_operand:DI 1 "arith_double_operand" "")
4714 (match_operand:DI 2 "arith_double_operand" "")))]
4718 (define_insn "*anddi3_sp32"
4719 [(set (match_operand:DI 0 "register_operand" "=r")
4720 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4721 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4725 (define_insn "*anddi3_sp64"
4726 [(set (match_operand:DI 0 "register_operand" "=r")
4727 (and:DI (match_operand:DI 1 "arith_operand" "%r")
4728 (match_operand:DI 2 "arith_operand" "rI")))]
4732 (define_insn "andsi3"
4733 [(set (match_operand:SI 0 "register_operand" "=r")
4734 (and:SI (match_operand:SI 1 "arith_operand" "%r")
4735 (match_operand:SI 2 "arith_operand" "rI")))]
4740 [(set (match_operand:SI 0 "register_operand" "")
4741 (and:SI (match_operand:SI 1 "register_operand" "")
4742 (match_operand:SI 2 "const_compl_high_operand" "")))
4743 (clobber (match_operand:SI 3 "register_operand" ""))]
4745 [(set (match_dup 3) (match_dup 4))
4746 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4748 operands[4] = GEN_INT (~INTVAL (operands[2]));
4751 (define_insn_and_split "*and_not_di_sp32"
4752 [(set (match_operand:DI 0 "register_operand" "=r")
4753 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4754 (match_operand:DI 2 "register_operand" "r")))]
4757 "&& reload_completed
4758 && ((GET_CODE (operands[0]) == REG
4759 && SPARC_INT_REG_P (REGNO (operands[0])))
4760 || (GET_CODE (operands[0]) == SUBREG
4761 && GET_CODE (SUBREG_REG (operands[0])) == REG
4762 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4763 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4764 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4765 "operands[3] = gen_highpart (SImode, operands[0]);
4766 operands[4] = gen_highpart (SImode, operands[1]);
4767 operands[5] = gen_highpart (SImode, operands[2]);
4768 operands[6] = gen_lowpart (SImode, operands[0]);
4769 operands[7] = gen_lowpart (SImode, operands[1]);
4770 operands[8] = gen_lowpart (SImode, operands[2]);"
4771 [(set_attr "length" "2")])
4773 (define_insn "*and_not_di_sp64"
4774 [(set (match_operand:DI 0 "register_operand" "=r")
4775 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4776 (match_operand:DI 2 "register_operand" "r")))]
4780 (define_insn "*and_not_si"
4781 [(set (match_operand:SI 0 "register_operand" "=r")
4782 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4783 (match_operand:SI 2 "register_operand" "r")))]
4787 (define_expand "iordi3"
4788 [(set (match_operand:DI 0 "register_operand" "")
4789 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4790 (match_operand:DI 2 "arith_double_operand" "")))]
4794 (define_insn "*iordi3_sp32"
4795 [(set (match_operand:DI 0 "register_operand" "=r")
4796 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4797 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4800 [(set_attr "length" "2")])
4802 (define_insn "*iordi3_sp64"
4803 [(set (match_operand:DI 0 "register_operand" "=r")
4804 (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4805 (match_operand:DI 2 "arith_operand" "rI")))]
4809 (define_insn "iorsi3"
4810 [(set (match_operand:SI 0 "register_operand" "=r")
4811 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4812 (match_operand:SI 2 "arith_operand" "rI")))]
4817 [(set (match_operand:SI 0 "register_operand" "")
4818 (ior:SI (match_operand:SI 1 "register_operand" "")
4819 (match_operand:SI 2 "const_compl_high_operand" "")))
4820 (clobber (match_operand:SI 3 "register_operand" ""))]
4822 [(set (match_dup 3) (match_dup 4))
4823 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4825 operands[4] = GEN_INT (~INTVAL (operands[2]));
4828 (define_insn_and_split "*or_not_di_sp32"
4829 [(set (match_operand:DI 0 "register_operand" "=r")
4830 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4831 (match_operand:DI 2 "register_operand" "r")))]
4834 "&& reload_completed
4835 && ((GET_CODE (operands[0]) == REG
4836 && SPARC_INT_REG_P (REGNO (operands[0])))
4837 || (GET_CODE (operands[0]) == SUBREG
4838 && GET_CODE (SUBREG_REG (operands[0])) == REG
4839 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4840 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4841 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4842 "operands[3] = gen_highpart (SImode, operands[0]);
4843 operands[4] = gen_highpart (SImode, operands[1]);
4844 operands[5] = gen_highpart (SImode, operands[2]);
4845 operands[6] = gen_lowpart (SImode, operands[0]);
4846 operands[7] = gen_lowpart (SImode, operands[1]);
4847 operands[8] = gen_lowpart (SImode, operands[2]);"
4848 [(set_attr "length" "2")])
4850 (define_insn "*or_not_di_sp64"
4851 [(set (match_operand:DI 0 "register_operand" "=r")
4852 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4853 (match_operand:DI 2 "register_operand" "r")))]
4857 (define_insn "*or_not_si"
4858 [(set (match_operand:SI 0 "register_operand" "=r")
4859 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4860 (match_operand:SI 2 "register_operand" "r")))]
4864 (define_expand "xordi3"
4865 [(set (match_operand:DI 0 "register_operand" "")
4866 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4867 (match_operand:DI 2 "arith_double_operand" "")))]
4871 (define_insn "*xordi3_sp32"
4872 [(set (match_operand:DI 0 "register_operand" "=r")
4873 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4874 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4877 [(set_attr "length" "2")])
4879 (define_insn "*xordi3_sp64"
4880 [(set (match_operand:DI 0 "register_operand" "=r")
4881 (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4882 (match_operand:DI 2 "arith_operand" "rI")))]
4886 (define_insn "xorsi3"
4887 [(set (match_operand:SI 0 "register_operand" "=r")
4888 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4889 (match_operand:SI 2 "arith_operand" "rI")))]
4894 [(set (match_operand:SI 0 "register_operand" "")
4895 (xor:SI (match_operand:SI 1 "register_operand" "")
4896 (match_operand:SI 2 "const_compl_high_operand" "")))
4897 (clobber (match_operand:SI 3 "register_operand" ""))]
4899 [(set (match_dup 3) (match_dup 4))
4900 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4902 operands[4] = GEN_INT (~INTVAL (operands[2]));
4906 [(set (match_operand:SI 0 "register_operand" "")
4907 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4908 (match_operand:SI 2 "const_compl_high_operand" ""))))
4909 (clobber (match_operand:SI 3 "register_operand" ""))]
4911 [(set (match_dup 3) (match_dup 4))
4912 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4914 operands[4] = GEN_INT (~INTVAL (operands[2]));
4917 ;; Split DImode logical operations requiring two instructions.
4919 [(set (match_operand:DI 0 "register_operand" "")
4920 (match_operator:DI 1 "cc_arith_operator" ; AND, IOR, XOR
4921 [(match_operand:DI 2 "register_operand" "")
4922 (match_operand:DI 3 "arith_double_operand" "")]))]
4925 && ((GET_CODE (operands[0]) == REG
4926 && SPARC_INT_REG_P (REGNO (operands[0])))
4927 || (GET_CODE (operands[0]) == SUBREG
4928 && GET_CODE (SUBREG_REG (operands[0])) == REG
4929 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4930 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4931 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4933 operands[4] = gen_highpart (SImode, operands[0]);
4934 operands[5] = gen_lowpart (SImode, operands[0]);
4935 operands[6] = gen_highpart (SImode, operands[2]);
4936 operands[7] = gen_lowpart (SImode, operands[2]);
4937 #if HOST_BITS_PER_WIDE_INT == 32
4938 if (GET_CODE (operands[3]) == CONST_INT)
4940 if (INTVAL (operands[3]) < 0)
4941 operands[8] = constm1_rtx;
4943 operands[8] = const0_rtx;
4947 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
4948 operands[9] = gen_lowpart (SImode, operands[3]);
4951 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4952 ;; Combine now canonicalizes to the rightmost expression.
4953 (define_insn_and_split "*xor_not_di_sp32"
4954 [(set (match_operand:DI 0 "register_operand" "=r")
4955 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
4956 (match_operand:DI 2 "register_operand" "r"))))]
4959 "&& reload_completed
4960 && ((GET_CODE (operands[0]) == REG
4961 && SPARC_INT_REG_P (REGNO (operands[0])))
4962 || (GET_CODE (operands[0]) == SUBREG
4963 && GET_CODE (SUBREG_REG (operands[0])) == REG
4964 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4965 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4966 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4967 "operands[3] = gen_highpart (SImode, operands[0]);
4968 operands[4] = gen_highpart (SImode, operands[1]);
4969 operands[5] = gen_highpart (SImode, operands[2]);
4970 operands[6] = gen_lowpart (SImode, operands[0]);
4971 operands[7] = gen_lowpart (SImode, operands[1]);
4972 operands[8] = gen_lowpart (SImode, operands[2]);"
4973 [(set_attr "length" "2")])
4975 (define_insn "*xor_not_di_sp64"
4976 [(set (match_operand:DI 0 "register_operand" "=r")
4977 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4978 (match_operand:DI 2 "arith_operand" "rI"))))]
4980 "xnor\t%r1, %2, %0")
4982 (define_insn "*xor_not_si"
4983 [(set (match_operand:SI 0 "register_operand" "=r")
4984 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4985 (match_operand:SI 2 "arith_operand" "rI"))))]
4987 "xnor\t%r1, %2, %0")
4989 ;; These correspond to the above in the case where we also (or only)
4990 ;; want to set the condition code.
4992 (define_insn "*cmp_cc_arith_op"
4993 [(set (reg:CC CC_REG)
4995 (match_operator:SI 2 "cc_arith_operator"
4996 [(match_operand:SI 0 "arith_operand" "%r")
4997 (match_operand:SI 1 "arith_operand" "rI")])
5000 "%A2cc\t%0, %1, %%g0"
5001 [(set_attr "type" "compare")])
5003 (define_insn "*cmp_ccx_arith_op"
5004 [(set (reg:CCX CC_REG)
5006 (match_operator:DI 2 "cc_arith_operator"
5007 [(match_operand:DI 0 "arith_operand" "%r")
5008 (match_operand:DI 1 "arith_operand" "rI")])
5011 "%A2cc\t%0, %1, %%g0"
5012 [(set_attr "type" "compare")])
5014 (define_insn "*cmp_cc_arith_op_set"
5015 [(set (reg:CC CC_REG)
5017 (match_operator:SI 3 "cc_arith_operator"
5018 [(match_operand:SI 1 "arith_operand" "%r")
5019 (match_operand:SI 2 "arith_operand" "rI")])
5021 (set (match_operand:SI 0 "register_operand" "=r")
5022 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5023 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5025 [(set_attr "type" "compare")])
5027 (define_insn "*cmp_ccx_arith_op_set"
5028 [(set (reg:CCX CC_REG)
5030 (match_operator:DI 3 "cc_arith_operator"
5031 [(match_operand:DI 1 "arith_operand" "%r")
5032 (match_operand:DI 2 "arith_operand" "rI")])
5034 (set (match_operand:DI 0 "register_operand" "=r")
5035 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5036 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5038 [(set_attr "type" "compare")])
5040 (define_insn "*cmp_cc_xor_not"
5041 [(set (reg:CC CC_REG)
5043 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5044 (match_operand:SI 1 "arith_operand" "rI")))
5047 "xnorcc\t%r0, %1, %%g0"
5048 [(set_attr "type" "compare")])
5050 (define_insn "*cmp_ccx_xor_not"
5051 [(set (reg:CCX CC_REG)
5053 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5054 (match_operand:DI 1 "arith_operand" "rI")))
5057 "xnorcc\t%r0, %1, %%g0"
5058 [(set_attr "type" "compare")])
5060 (define_insn "*cmp_cc_xor_not_set"
5061 [(set (reg:CC CC_REG)
5063 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5064 (match_operand:SI 2 "arith_operand" "rI")))
5066 (set (match_operand:SI 0 "register_operand" "=r")
5067 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5069 "xnorcc\t%r1, %2, %0"
5070 [(set_attr "type" "compare")])
5072 (define_insn "*cmp_ccx_xor_not_set"
5073 [(set (reg:CCX CC_REG)
5075 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5076 (match_operand:DI 2 "arith_operand" "rI")))
5078 (set (match_operand:DI 0 "register_operand" "=r")
5079 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5081 "xnorcc\t%r1, %2, %0"
5082 [(set_attr "type" "compare")])
5084 (define_insn "*cmp_cc_arith_op_not"
5085 [(set (reg:CC CC_REG)
5087 (match_operator:SI 2 "cc_arith_not_operator"
5088 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5089 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5092 "%B2cc\t%r1, %0, %%g0"
5093 [(set_attr "type" "compare")])
5095 (define_insn "*cmp_ccx_arith_op_not"
5096 [(set (reg:CCX CC_REG)
5098 (match_operator:DI 2 "cc_arith_not_operator"
5099 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5100 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5103 "%B2cc\t%r1, %0, %%g0"
5104 [(set_attr "type" "compare")])
5106 (define_insn "*cmp_cc_arith_op_not_set"
5107 [(set (reg:CC CC_REG)
5109 (match_operator:SI 3 "cc_arith_not_operator"
5110 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5111 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5113 (set (match_operand:SI 0 "register_operand" "=r")
5114 (match_operator:SI 4 "cc_arith_not_operator"
5115 [(not:SI (match_dup 1)) (match_dup 2)]))]
5116 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5117 "%B3cc\t%r2, %1, %0"
5118 [(set_attr "type" "compare")])
5120 (define_insn "*cmp_ccx_arith_op_not_set"
5121 [(set (reg:CCX CC_REG)
5123 (match_operator:DI 3 "cc_arith_not_operator"
5124 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5125 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5127 (set (match_operand:DI 0 "register_operand" "=r")
5128 (match_operator:DI 4 "cc_arith_not_operator"
5129 [(not:DI (match_dup 1)) (match_dup 2)]))]
5130 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5131 "%B3cc\t%r2, %1, %0"
5132 [(set_attr "type" "compare")])
5134 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5135 ;; does not know how to make it work for constants.
5137 (define_expand "negdi2"
5138 [(set (match_operand:DI 0 "register_operand" "=r")
5139 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5142 if (! TARGET_ARCH64)
5144 emit_insn (gen_rtx_PARALLEL
5147 gen_rtx_SET (VOIDmode, operand0,
5148 gen_rtx_NEG (DImode, operand1)),
5149 gen_rtx_CLOBBER (VOIDmode,
5150 gen_rtx_REG (CCmode,
5156 (define_insn_and_split "*negdi2_sp32"
5157 [(set (match_operand:DI 0 "register_operand" "=r")
5158 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5159 (clobber (reg:CC CC_REG))]
5162 "&& reload_completed"
5163 [(parallel [(set (reg:CC_NOOV CC_REG)
5164 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5166 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5167 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5168 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5169 "operands[2] = gen_highpart (SImode, operands[0]);
5170 operands[3] = gen_highpart (SImode, operands[1]);
5171 operands[4] = gen_lowpart (SImode, operands[0]);
5172 operands[5] = gen_lowpart (SImode, operands[1]);"
5173 [(set_attr "length" "2")])
5175 (define_insn "*negdi2_sp64"
5176 [(set (match_operand:DI 0 "register_operand" "=r")
5177 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5179 "sub\t%%g0, %1, %0")
5181 (define_insn "negsi2"
5182 [(set (match_operand:SI 0 "register_operand" "=r")
5183 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5185 "sub\t%%g0, %1, %0")
5187 (define_insn "*cmp_cc_neg"
5188 [(set (reg:CC_NOOV CC_REG)
5189 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5192 "subcc\t%%g0, %0, %%g0"
5193 [(set_attr "type" "compare")])
5195 (define_insn "*cmp_ccx_neg"
5196 [(set (reg:CCX_NOOV CC_REG)
5197 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5200 "subcc\t%%g0, %0, %%g0"
5201 [(set_attr "type" "compare")])
5203 (define_insn "*cmp_cc_set_neg"
5204 [(set (reg:CC_NOOV CC_REG)
5205 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5207 (set (match_operand:SI 0 "register_operand" "=r")
5208 (neg:SI (match_dup 1)))]
5210 "subcc\t%%g0, %1, %0"
5211 [(set_attr "type" "compare")])
5213 (define_insn "*cmp_ccx_set_neg"
5214 [(set (reg:CCX_NOOV CC_REG)
5215 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5217 (set (match_operand:DI 0 "register_operand" "=r")
5218 (neg:DI (match_dup 1)))]
5220 "subcc\t%%g0, %1, %0"
5221 [(set_attr "type" "compare")])
5223 ;; We cannot use the "not" pseudo insn because the Sun assembler
5224 ;; does not know how to make it work for constants.
5225 (define_expand "one_cmpldi2"
5226 [(set (match_operand:DI 0 "register_operand" "")
5227 (not:DI (match_operand:DI 1 "register_operand" "")))]
5231 (define_insn_and_split "*one_cmpldi2_sp32"
5232 [(set (match_operand:DI 0 "register_operand" "=r")
5233 (not:DI (match_operand:DI 1 "register_operand" "r")))]
5236 "&& reload_completed
5237 && ((GET_CODE (operands[0]) == REG
5238 && SPARC_INT_REG_P (REGNO (operands[0])))
5239 || (GET_CODE (operands[0]) == SUBREG
5240 && GET_CODE (SUBREG_REG (operands[0])) == REG
5241 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
5242 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5243 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5244 "operands[2] = gen_highpart (SImode, operands[0]);
5245 operands[3] = gen_highpart (SImode, operands[1]);
5246 operands[4] = gen_lowpart (SImode, operands[0]);
5247 operands[5] = gen_lowpart (SImode, operands[1]);"
5248 [(set_attr "length" "2")])
5250 (define_insn "*one_cmpldi2_sp64"
5251 [(set (match_operand:DI 0 "register_operand" "=r")
5252 (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5254 "xnor\t%%g0, %1, %0")
5256 (define_insn "one_cmplsi2"
5257 [(set (match_operand:SI 0 "register_operand" "=r")
5258 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5260 "xnor\t%%g0, %1, %0")
5262 (define_insn "*cmp_cc_not"
5263 [(set (reg:CC CC_REG)
5264 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5267 "xnorcc\t%%g0, %0, %%g0"
5268 [(set_attr "type" "compare")])
5270 (define_insn "*cmp_ccx_not"
5271 [(set (reg:CCX CC_REG)
5272 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5275 "xnorcc\t%%g0, %0, %%g0"
5276 [(set_attr "type" "compare")])
5278 (define_insn "*cmp_cc_set_not"
5279 [(set (reg:CC CC_REG)
5280 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5282 (set (match_operand:SI 0 "register_operand" "=r")
5283 (not:SI (match_dup 1)))]
5285 "xnorcc\t%%g0, %1, %0"
5286 [(set_attr "type" "compare")])
5288 (define_insn "*cmp_ccx_set_not"
5289 [(set (reg:CCX CC_REG)
5290 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5292 (set (match_operand:DI 0 "register_operand" "=r")
5293 (not:DI (match_dup 1)))]
5295 "xnorcc\t%%g0, %1, %0"
5296 [(set_attr "type" "compare")])
5298 (define_insn "*cmp_cc_set"
5299 [(set (match_operand:SI 0 "register_operand" "=r")
5300 (match_operand:SI 1 "register_operand" "r"))
5301 (set (reg:CC CC_REG)
5302 (compare:CC (match_dup 1)
5306 [(set_attr "type" "compare")])
5308 (define_insn "*cmp_ccx_set64"
5309 [(set (match_operand:DI 0 "register_operand" "=r")
5310 (match_operand:DI 1 "register_operand" "r"))
5311 (set (reg:CCX CC_REG)
5312 (compare:CCX (match_dup 1)
5316 [(set_attr "type" "compare")])
5319 ;; Floating point arithmetic instructions.
5321 (define_expand "addtf3"
5322 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5323 (plus:TF (match_operand:TF 1 "general_operand" "")
5324 (match_operand:TF 2 "general_operand" "")))]
5325 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5326 "emit_tfmode_binop (PLUS, operands); DONE;")
5328 (define_insn "*addtf3_hq"
5329 [(set (match_operand:TF 0 "register_operand" "=e")
5330 (plus:TF (match_operand:TF 1 "register_operand" "e")
5331 (match_operand:TF 2 "register_operand" "e")))]
5332 "TARGET_FPU && TARGET_HARD_QUAD"
5334 [(set_attr "type" "fp")])
5336 (define_insn "adddf3"
5337 [(set (match_operand:DF 0 "register_operand" "=e")
5338 (plus:DF (match_operand:DF 1 "register_operand" "e")
5339 (match_operand:DF 2 "register_operand" "e")))]
5342 [(set_attr "type" "fp")
5343 (set_attr "fptype" "double")])
5345 (define_insn "addsf3"
5346 [(set (match_operand:SF 0 "register_operand" "=f")
5347 (plus:SF (match_operand:SF 1 "register_operand" "f")
5348 (match_operand:SF 2 "register_operand" "f")))]
5351 [(set_attr "type" "fp")])
5353 (define_expand "subtf3"
5354 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5355 (minus:TF (match_operand:TF 1 "general_operand" "")
5356 (match_operand:TF 2 "general_operand" "")))]
5357 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5358 "emit_tfmode_binop (MINUS, operands); DONE;")
5360 (define_insn "*subtf3_hq"
5361 [(set (match_operand:TF 0 "register_operand" "=e")
5362 (minus:TF (match_operand:TF 1 "register_operand" "e")
5363 (match_operand:TF 2 "register_operand" "e")))]
5364 "TARGET_FPU && TARGET_HARD_QUAD"
5366 [(set_attr "type" "fp")])
5368 (define_insn "subdf3"
5369 [(set (match_operand:DF 0 "register_operand" "=e")
5370 (minus:DF (match_operand:DF 1 "register_operand" "e")
5371 (match_operand:DF 2 "register_operand" "e")))]
5374 [(set_attr "type" "fp")
5375 (set_attr "fptype" "double")])
5377 (define_insn "subsf3"
5378 [(set (match_operand:SF 0 "register_operand" "=f")
5379 (minus:SF (match_operand:SF 1 "register_operand" "f")
5380 (match_operand:SF 2 "register_operand" "f")))]
5383 [(set_attr "type" "fp")])
5385 (define_expand "multf3"
5386 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5387 (mult:TF (match_operand:TF 1 "general_operand" "")
5388 (match_operand:TF 2 "general_operand" "")))]
5389 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5390 "emit_tfmode_binop (MULT, operands); DONE;")
5392 (define_insn "*multf3_hq"
5393 [(set (match_operand:TF 0 "register_operand" "=e")
5394 (mult:TF (match_operand:TF 1 "register_operand" "e")
5395 (match_operand:TF 2 "register_operand" "e")))]
5396 "TARGET_FPU && TARGET_HARD_QUAD"
5398 [(set_attr "type" "fpmul")])
5400 (define_insn "muldf3"
5401 [(set (match_operand:DF 0 "register_operand" "=e")
5402 (mult:DF (match_operand:DF 1 "register_operand" "e")
5403 (match_operand:DF 2 "register_operand" "e")))]
5406 [(set_attr "type" "fpmul")
5407 (set_attr "fptype" "double")])
5409 (define_insn "mulsf3"
5410 [(set (match_operand:SF 0 "register_operand" "=f")
5411 (mult:SF (match_operand:SF 1 "register_operand" "f")
5412 (match_operand:SF 2 "register_operand" "f")))]
5415 [(set_attr "type" "fpmul")])
5417 (define_insn "fmadf4"
5418 [(set (match_operand:DF 0 "register_operand" "=e")
5419 (fma:DF (match_operand:DF 1 "register_operand" "e")
5420 (match_operand:DF 2 "register_operand" "e")
5421 (match_operand:DF 3 "register_operand" "e")))]
5423 "fmaddd\t%1, %2, %3, %0"
5424 [(set_attr "type" "fpmul")])
5426 (define_insn "fmsdf4"
5427 [(set (match_operand:DF 0 "register_operand" "=e")
5428 (fma:DF (match_operand:DF 1 "register_operand" "e")
5429 (match_operand:DF 2 "register_operand" "e")
5430 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5432 "fmsubd\t%1, %2, %3, %0"
5433 [(set_attr "type" "fpmul")])
5435 (define_insn "*nfmadf4"
5436 [(set (match_operand:DF 0 "register_operand" "=e")
5437 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5438 (match_operand:DF 2 "register_operand" "e")
5439 (match_operand:DF 3 "register_operand" "e"))))]
5441 "fnmaddd\t%1, %2, %3, %0"
5442 [(set_attr "type" "fpmul")])
5444 (define_insn "*nfmsdf4"
5445 [(set (match_operand:DF 0 "register_operand" "=e")
5446 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5447 (match_operand:DF 2 "register_operand" "e")
5448 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5450 "fnmsubd\t%1, %2, %3, %0"
5451 [(set_attr "type" "fpmul")])
5453 (define_insn "fmasf4"
5454 [(set (match_operand:SF 0 "register_operand" "=f")
5455 (fma:SF (match_operand:SF 1 "register_operand" "f")
5456 (match_operand:SF 2 "register_operand" "f")
5457 (match_operand:SF 3 "register_operand" "f")))]
5459 "fmadds\t%1, %2, %3, %0"
5460 [(set_attr "type" "fpmul")])
5462 (define_insn "fmssf4"
5463 [(set (match_operand:SF 0 "register_operand" "=f")
5464 (fma:SF (match_operand:SF 1 "register_operand" "f")
5465 (match_operand:SF 2 "register_operand" "f")
5466 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5468 "fmsubs\t%1, %2, %3, %0"
5469 [(set_attr "type" "fpmul")])
5471 (define_insn "*nfmasf4"
5472 [(set (match_operand:SF 0 "register_operand" "=f")
5473 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5474 (match_operand:SF 2 "register_operand" "f")
5475 (match_operand:SF 3 "register_operand" "f"))))]
5477 "fnmadds\t%1, %2, %3, %0"
5478 [(set_attr "type" "fpmul")])
5480 (define_insn "*nfmssf4"
5481 [(set (match_operand:SF 0 "register_operand" "=f")
5482 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5483 (match_operand:SF 2 "register_operand" "f")
5484 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5486 "fnmsubs\t%1, %2, %3, %0"
5487 [(set_attr "type" "fpmul")])
5489 (define_insn "*muldf3_extend"
5490 [(set (match_operand:DF 0 "register_operand" "=e")
5491 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5492 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5493 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699"
5494 "fsmuld\t%1, %2, %0"
5495 [(set_attr "type" "fpmul")
5496 (set_attr "fptype" "double")])
5498 (define_insn "*multf3_extend"
5499 [(set (match_operand:TF 0 "register_operand" "=e")
5500 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5501 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5502 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5503 "fdmulq\t%1, %2, %0"
5504 [(set_attr "type" "fpmul")])
5506 (define_expand "divtf3"
5507 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5508 (div:TF (match_operand:TF 1 "general_operand" "")
5509 (match_operand:TF 2 "general_operand" "")))]
5510 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5511 "emit_tfmode_binop (DIV, operands); DONE;")
5513 ;; don't have timing for quad-prec. divide.
5514 (define_insn "*divtf3_hq"
5515 [(set (match_operand:TF 0 "register_operand" "=e")
5516 (div:TF (match_operand:TF 1 "register_operand" "e")
5517 (match_operand:TF 2 "register_operand" "e")))]
5518 "TARGET_FPU && TARGET_HARD_QUAD"
5520 [(set_attr "type" "fpdivs")])
5522 (define_expand "divdf3"
5523 [(set (match_operand:DF 0 "register_operand" "=e")
5524 (div:DF (match_operand:DF 1 "register_operand" "e")
5525 (match_operand:DF 2 "register_operand" "e")))]
5529 (define_insn "*divdf3_nofix"
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")))]
5533 "TARGET_FPU && !sparc_fix_ut699"
5535 [(set_attr "type" "fpdivd")
5536 (set_attr "fptype" "double")])
5538 (define_insn "*divdf3_fix"
5539 [(set (match_operand:DF 0 "register_operand" "=e")
5540 (div:DF (match_operand:DF 1 "register_operand" "e")
5541 (match_operand:DF 2 "register_operand" "e")))]
5542 "TARGET_FPU && sparc_fix_ut699"
5543 "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]"
5544 [(set_attr "type" "fpdivd")
5545 (set_attr "fptype" "double")
5546 (set_attr "length" "2")])
5548 (define_insn "divsf3"
5549 [(set (match_operand:SF 0 "register_operand" "=f")
5550 (div:SF (match_operand:SF 1 "register_operand" "f")
5551 (match_operand:SF 2 "register_operand" "f")))]
5552 "TARGET_FPU && !sparc_fix_ut699"
5554 [(set_attr "type" "fpdivs")])
5556 (define_expand "negtf2"
5557 [(set (match_operand:TF 0 "register_operand" "=e,e")
5558 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5562 (define_insn_and_split "*negtf2_notv9"
5563 [(set (match_operand:TF 0 "register_operand" "=e,e")
5564 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5565 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5571 "&& reload_completed
5572 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5573 [(set (match_dup 2) (neg:SF (match_dup 3)))
5574 (set (match_dup 4) (match_dup 5))
5575 (set (match_dup 6) (match_dup 7))]
5576 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5577 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5578 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5579 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5580 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5581 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5582 [(set_attr "type" "fpmove,*")
5583 (set_attr "length" "*,2")])
5585 (define_insn_and_split "*negtf2_v9"
5586 [(set (match_operand:TF 0 "register_operand" "=e,e")
5587 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5588 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5589 "TARGET_FPU && TARGET_V9"
5593 "&& reload_completed
5594 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5595 [(set (match_dup 2) (neg:DF (match_dup 3)))
5596 (set (match_dup 4) (match_dup 5))]
5597 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5598 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5599 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5600 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5601 [(set_attr "type" "fpmove,*")
5602 (set_attr "length" "*,2")
5603 (set_attr "fptype" "double")])
5605 (define_expand "negdf2"
5606 [(set (match_operand:DF 0 "register_operand" "")
5607 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5611 (define_insn_and_split "*negdf2_notv9"
5612 [(set (match_operand:DF 0 "register_operand" "=e,e")
5613 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5614 "TARGET_FPU && ! TARGET_V9"
5618 "&& reload_completed
5619 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5620 [(set (match_dup 2) (neg:SF (match_dup 3)))
5621 (set (match_dup 4) (match_dup 5))]
5622 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5623 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5624 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5625 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5626 [(set_attr "type" "fpmove,*")
5627 (set_attr "length" "*,2")])
5629 (define_insn "*negdf2_v9"
5630 [(set (match_operand:DF 0 "register_operand" "=e")
5631 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5632 "TARGET_FPU && TARGET_V9"
5634 [(set_attr "type" "fpmove")
5635 (set_attr "fptype" "double")])
5637 (define_insn "negsf2"
5638 [(set (match_operand:SF 0 "register_operand" "=f")
5639 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5642 [(set_attr "type" "fpmove")])
5644 (define_expand "abstf2"
5645 [(set (match_operand:TF 0 "register_operand" "")
5646 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5650 (define_insn_and_split "*abstf2_notv9"
5651 [(set (match_operand:TF 0 "register_operand" "=e,e")
5652 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5653 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5654 "TARGET_FPU && ! TARGET_V9"
5658 "&& reload_completed
5659 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5660 [(set (match_dup 2) (abs:SF (match_dup 3)))
5661 (set (match_dup 4) (match_dup 5))
5662 (set (match_dup 6) (match_dup 7))]
5663 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5664 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5665 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5666 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5667 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5668 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5669 [(set_attr "type" "fpmove,*")
5670 (set_attr "length" "*,2")])
5672 (define_insn "*abstf2_hq_v9"
5673 [(set (match_operand:TF 0 "register_operand" "=e,e")
5674 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5675 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5679 [(set_attr "type" "fpmove")
5680 (set_attr "fptype" "double,*")])
5682 (define_insn_and_split "*abstf2_v9"
5683 [(set (match_operand:TF 0 "register_operand" "=e,e")
5684 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5685 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5689 "&& reload_completed
5690 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5691 [(set (match_dup 2) (abs:DF (match_dup 3)))
5692 (set (match_dup 4) (match_dup 5))]
5693 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5694 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5695 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5696 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5697 [(set_attr "type" "fpmove,*")
5698 (set_attr "length" "*,2")
5699 (set_attr "fptype" "double,*")])
5701 (define_expand "absdf2"
5702 [(set (match_operand:DF 0 "register_operand" "")
5703 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5707 (define_insn_and_split "*absdf2_notv9"
5708 [(set (match_operand:DF 0 "register_operand" "=e,e")
5709 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5710 "TARGET_FPU && ! TARGET_V9"
5714 "&& reload_completed
5715 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5716 [(set (match_dup 2) (abs:SF (match_dup 3)))
5717 (set (match_dup 4) (match_dup 5))]
5718 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5719 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5720 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5721 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5722 [(set_attr "type" "fpmove,*")
5723 (set_attr "length" "*,2")])
5725 (define_insn "*absdf2_v9"
5726 [(set (match_operand:DF 0 "register_operand" "=e")
5727 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5728 "TARGET_FPU && TARGET_V9"
5730 [(set_attr "type" "fpmove")
5731 (set_attr "fptype" "double")])
5733 (define_insn "abssf2"
5734 [(set (match_operand:SF 0 "register_operand" "=f")
5735 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5738 [(set_attr "type" "fpmove")])
5740 (define_expand "sqrttf2"
5741 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5742 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5743 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5744 "emit_tfmode_unop (SQRT, operands); DONE;")
5746 (define_insn "*sqrttf2_hq"
5747 [(set (match_operand:TF 0 "register_operand" "=e")
5748 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5749 "TARGET_FPU && TARGET_HARD_QUAD"
5751 [(set_attr "type" "fpsqrts")])
5753 (define_expand "sqrtdf2"
5754 [(set (match_operand:DF 0 "register_operand" "=e")
5755 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5759 (define_insn "*sqrtdf2_nofix"
5760 [(set (match_operand:DF 0 "register_operand" "=e")
5761 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5762 "TARGET_FPU && !sparc_fix_ut699"
5764 [(set_attr "type" "fpsqrtd")
5765 (set_attr "fptype" "double")])
5767 (define_insn "*sqrtdf2_fix"
5768 [(set (match_operand:DF 0 "register_operand" "=e")
5769 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5770 "TARGET_FPU && sparc_fix_ut699"
5771 "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]"
5772 [(set_attr "type" "fpsqrtd")
5773 (set_attr "fptype" "double")
5774 (set_attr "length" "2")])
5776 (define_insn "sqrtsf2"
5777 [(set (match_operand:SF 0 "register_operand" "=f")
5778 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5779 "TARGET_FPU && !sparc_fix_ut699"
5781 [(set_attr "type" "fpsqrts")])
5784 ;; Arithmetic shift instructions.
5786 (define_insn "ashlsi3"
5787 [(set (match_operand:SI 0 "register_operand" "=r")
5788 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5789 (match_operand:SI 2 "arith_operand" "rI")))]
5792 if (GET_CODE (operands[2]) == CONST_INT)
5793 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5794 return "sll\t%1, %2, %0";
5796 [(set_attr "type" "shift")])
5798 (define_expand "ashldi3"
5799 [(set (match_operand:DI 0 "register_operand" "=r")
5800 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5801 (match_operand:SI 2 "arith_operand" "rI")))]
5802 "TARGET_ARCH64 || TARGET_V8PLUS"
5804 if (! TARGET_ARCH64)
5806 if (GET_CODE (operands[2]) == CONST_INT)
5808 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5813 (define_insn "*ashldi3_sp64"
5814 [(set (match_operand:DI 0 "register_operand" "=r")
5815 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5816 (match_operand:SI 2 "arith_operand" "rI")))]
5819 if (GET_CODE (operands[2]) == CONST_INT)
5820 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5821 return "sllx\t%1, %2, %0";
5823 [(set_attr "type" "shift")])
5826 (define_insn "ashldi3_v8plus"
5827 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5828 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5829 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5830 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5832 "* return output_v8plus_shift (insn ,operands, \"sllx\");"
5833 [(set_attr "type" "multi")
5834 (set_attr "length" "5,5,6")])
5836 ;; Optimize (1LL<<x)-1
5837 ;; XXX this also needs to be fixed to handle equal subregs
5838 ;; XXX first before we could re-enable it.
5840 ; [(set (match_operand:DI 0 "register_operand" "=h")
5841 ; (plus:DI (ashift:DI (const_int 1)
5842 ; (match_operand:SI 1 "arith_operand" "rI"))
5844 ; "0 && TARGET_V8PLUS"
5846 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5847 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5848 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5850 ; [(set_attr "type" "multi")
5851 ; (set_attr "length" "4")])
5853 (define_insn "*cmp_cc_ashift_1"
5854 [(set (reg:CC_NOOV CC_REG)
5855 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5859 "addcc\t%0, %0, %%g0"
5860 [(set_attr "type" "compare")])
5862 (define_insn "*cmp_cc_set_ashift_1"
5863 [(set (reg:CC_NOOV CC_REG)
5864 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5867 (set (match_operand:SI 0 "register_operand" "=r")
5868 (ashift:SI (match_dup 1) (const_int 1)))]
5871 [(set_attr "type" "compare")])
5873 (define_insn "ashrsi3"
5874 [(set (match_operand:SI 0 "register_operand" "=r")
5875 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5876 (match_operand:SI 2 "arith_operand" "rI")))]
5879 if (GET_CODE (operands[2]) == CONST_INT)
5880 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5881 return "sra\t%1, %2, %0";
5883 [(set_attr "type" "shift")])
5885 (define_insn "*ashrsi3_extend"
5886 [(set (match_operand:DI 0 "register_operand" "=r")
5887 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5888 (match_operand:SI 2 "arith_operand" "r"))))]
5891 [(set_attr "type" "shift")])
5893 ;; This handles the case as above, but with constant shift instead of
5894 ;; register. Combiner "simplifies" it for us a little bit though.
5895 (define_insn "*ashrsi3_extend2"
5896 [(set (match_operand:DI 0 "register_operand" "=r")
5897 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5899 (match_operand:SI 2 "small_int_operand" "I")))]
5900 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5902 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5903 return "sra\t%1, %2, %0";
5905 [(set_attr "type" "shift")])
5907 (define_expand "ashrdi3"
5908 [(set (match_operand:DI 0 "register_operand" "=r")
5909 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5910 (match_operand:SI 2 "arith_operand" "rI")))]
5911 "TARGET_ARCH64 || TARGET_V8PLUS"
5913 if (! TARGET_ARCH64)
5915 if (GET_CODE (operands[2]) == CONST_INT)
5916 FAIL; /* prefer generic code in this case */
5917 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5922 (define_insn "*ashrdi3_sp64"
5923 [(set (match_operand:DI 0 "register_operand" "=r")
5924 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5925 (match_operand:SI 2 "arith_operand" "rI")))]
5929 if (GET_CODE (operands[2]) == CONST_INT)
5930 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5931 return "srax\t%1, %2, %0";
5933 [(set_attr "type" "shift")])
5936 (define_insn "ashrdi3_v8plus"
5937 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5938 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5939 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5940 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5942 "* return output_v8plus_shift (insn, operands, \"srax\");"
5943 [(set_attr "type" "multi")
5944 (set_attr "length" "5,5,6")])
5946 (define_insn "lshrsi3"
5947 [(set (match_operand:SI 0 "register_operand" "=r")
5948 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5949 (match_operand:SI 2 "arith_operand" "rI")))]
5952 if (GET_CODE (operands[2]) == CONST_INT)
5953 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5954 return "srl\t%1, %2, %0";
5956 [(set_attr "type" "shift")])
5958 (define_insn "*lshrsi3_extend0"
5959 [(set (match_operand:DI 0 "register_operand" "=r")
5961 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5962 (match_operand:SI 2 "arith_operand" "rI"))))]
5965 if (GET_CODE (operands[2]) == CONST_INT)
5966 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5967 return "srl\t%1, %2, %0";
5969 [(set_attr "type" "shift")])
5971 ;; This handles the case where
5972 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5973 ;; but combiner "simplifies" it for us.
5974 (define_insn "*lshrsi3_extend1"
5975 [(set (match_operand:DI 0 "register_operand" "=r")
5976 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5977 (match_operand:SI 2 "arith_operand" "r")) 0)
5978 (match_operand 3 "const_int_operand" "")))]
5979 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5981 [(set_attr "type" "shift")])
5983 ;; This handles the case where
5984 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5985 ;; but combiner "simplifies" it for us.
5986 (define_insn "*lshrsi3_extend2"
5987 [(set (match_operand:DI 0 "register_operand" "=r")
5988 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5989 (match_operand 2 "small_int_operand" "I")
5991 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5993 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5994 return "srl\t%1, %2, %0";
5996 [(set_attr "type" "shift")])
5998 (define_expand "lshrdi3"
5999 [(set (match_operand:DI 0 "register_operand" "=r")
6000 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6001 (match_operand:SI 2 "arith_operand" "rI")))]
6002 "TARGET_ARCH64 || TARGET_V8PLUS"
6004 if (! TARGET_ARCH64)
6006 if (GET_CODE (operands[2]) == CONST_INT)
6008 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6013 (define_insn "*lshrdi3_sp64"
6014 [(set (match_operand:DI 0 "register_operand" "=r")
6015 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6016 (match_operand:SI 2 "arith_operand" "rI")))]
6019 if (GET_CODE (operands[2]) == CONST_INT)
6020 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6021 return "srlx\t%1, %2, %0";
6023 [(set_attr "type" "shift")])
6026 (define_insn "lshrdi3_v8plus"
6027 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6028 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6029 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6030 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6032 "* return output_v8plus_shift (insn, operands, \"srlx\");"
6033 [(set_attr "type" "multi")
6034 (set_attr "length" "5,5,6")])
6037 [(set (match_operand:SI 0 "register_operand" "=r")
6038 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6040 (match_operand:SI 2 "small_int_operand" "I")))]
6041 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6043 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6044 return "srax\t%1, %2, %0";
6046 [(set_attr "type" "shift")])
6049 [(set (match_operand:SI 0 "register_operand" "=r")
6050 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6052 (match_operand:SI 2 "small_int_operand" "I")))]
6053 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6055 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6056 return "srlx\t%1, %2, %0";
6058 [(set_attr "type" "shift")])
6061 [(set (match_operand:SI 0 "register_operand" "=r")
6062 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6063 (match_operand:SI 2 "small_int_operand" "I")) 4)
6064 (match_operand:SI 3 "small_int_operand" "I")))]
6066 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6067 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6068 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6070 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6072 return "srax\t%1, %2, %0";
6074 [(set_attr "type" "shift")])
6077 [(set (match_operand:SI 0 "register_operand" "=r")
6078 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6079 (match_operand:SI 2 "small_int_operand" "I")) 4)
6080 (match_operand:SI 3 "small_int_operand" "I")))]
6082 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6083 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6084 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6086 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6088 return "srlx\t%1, %2, %0";
6090 [(set_attr "type" "shift")])
6093 ;; Unconditional and other jump instructions.
6095 (define_expand "jump"
6096 [(set (pc) (label_ref (match_operand 0 "" "")))]
6099 (define_insn "*jump_ubranch"
6100 [(set (pc) (label_ref (match_operand 0 "" "")))]
6102 "* return output_ubranch (operands[0], insn);"
6103 [(set_attr "type" "uncond_branch")])
6105 (define_insn "*jump_cbcond"
6106 [(set (pc) (label_ref (match_operand 0 "" "")))]
6108 "* return output_ubranch (operands[0], insn);"
6109 [(set_attr "type" "uncond_cbcond")])
6111 (define_expand "tablejump"
6112 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6113 (use (label_ref (match_operand 1 "" "")))])]
6116 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6118 /* In pic mode, our address differences are against the base of the
6119 table. Add that base value back in; CSE ought to be able to combine
6120 the two address loads. */
6124 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6126 if (CASE_VECTOR_MODE != Pmode)
6127 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6128 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6129 operands[0] = memory_address (Pmode, tmp);
6133 (define_insn "*tablejump_sp32"
6134 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6135 (use (label_ref (match_operand 1 "" "")))]
6138 [(set_attr "type" "uncond_branch")])
6140 (define_insn "*tablejump_sp64"
6141 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6142 (use (label_ref (match_operand 1 "" "")))]
6145 [(set_attr "type" "uncond_branch")])
6148 ;; Jump to subroutine instructions.
6150 (define_expand "call"
6151 ;; Note that this expression is not used for generating RTL.
6152 ;; All the RTL is generated explicitly below.
6153 [(call (match_operand 0 "call_operand" "")
6154 (match_operand 3 "" "i"))]
6155 ;; operands[2] is next_arg_register
6156 ;; operands[3] is struct_value_size_rtx.
6161 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6163 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6165 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6167 /* This is really a PIC sequence. We want to represent
6168 it as a funny jump so its delay slots can be filled.
6170 ??? But if this really *is* a CALL, will not it clobber the
6171 call-clobbered registers? We lose this if it is a JUMP_INSN.
6172 Why cannot we have delay slots filled if it were a CALL? */
6174 /* We accept negative sizes for untyped calls. */
6175 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6180 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6182 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6188 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6189 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6193 fn_rtx = operands[0];
6195 /* We accept negative sizes for untyped calls. */
6196 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6197 sparc_emit_call_insn
6200 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6202 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6205 sparc_emit_call_insn
6208 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6209 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6217 ;; We can't use the same pattern for these two insns, because then registers
6218 ;; in the address may not be properly reloaded.
6220 (define_insn "*call_address_sp32"
6221 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6222 (match_operand 1 "" ""))
6223 (clobber (reg:SI O7_REG))]
6224 ;;- Do not use operand 1 for most machines.
6227 [(set_attr "type" "call")])
6229 (define_insn "*call_symbolic_sp32"
6230 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6231 (match_operand 1 "" ""))
6232 (clobber (reg:SI O7_REG))]
6233 ;;- Do not use operand 1 for most machines.
6236 [(set_attr "type" "call")])
6238 (define_insn "*call_address_sp64"
6239 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6240 (match_operand 1 "" ""))
6241 (clobber (reg:DI O7_REG))]
6242 ;;- Do not use operand 1 for most machines.
6245 [(set_attr "type" "call")])
6247 (define_insn "*call_symbolic_sp64"
6248 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6249 (match_operand 1 "" ""))
6250 (clobber (reg:DI O7_REG))]
6251 ;;- Do not use operand 1 for most machines.
6254 [(set_attr "type" "call")])
6256 ;; This is a call that wants a structure value.
6257 ;; There is no such critter for v9 (??? we may need one anyway).
6258 (define_insn "*call_address_struct_value_sp32"
6259 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6260 (match_operand 1 "" ""))
6261 (match_operand 2 "immediate_operand" "")
6262 (clobber (reg:SI O7_REG))]
6263 ;;- Do not use operand 1 for most machines.
6264 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6266 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6267 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6269 [(set_attr "type" "call_no_delay_slot")
6270 (set_attr "length" "3")])
6272 ;; This is a call that wants a structure value.
6273 ;; There is no such critter for v9 (??? we may need one anyway).
6274 (define_insn "*call_symbolic_struct_value_sp32"
6275 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6276 (match_operand 1 "" ""))
6277 (match_operand 2 "immediate_operand" "")
6278 (clobber (reg:SI O7_REG))]
6279 ;;- Do not use operand 1 for most machines.
6280 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6282 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6283 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6285 [(set_attr "type" "call_no_delay_slot")
6286 (set_attr "length" "3")])
6288 ;; This is a call that may want a structure value. This is used for
6290 (define_insn "*call_address_untyped_struct_value_sp32"
6291 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6292 (match_operand 1 "" ""))
6293 (match_operand 2 "immediate_operand" "")
6294 (clobber (reg:SI O7_REG))]
6295 ;;- Do not use operand 1 for most machines.
6296 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6297 "call\t%a0, %1\n\t nop\n\tnop"
6298 [(set_attr "type" "call_no_delay_slot")
6299 (set_attr "length" "3")])
6301 ;; This is a call that may want a structure value. This is used for
6303 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6304 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6305 (match_operand 1 "" ""))
6306 (match_operand 2 "immediate_operand" "")
6307 (clobber (reg:SI O7_REG))]
6308 ;;- Do not use operand 1 for most machines.
6309 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6310 "call\t%a0, %1\n\t nop\n\tnop"
6311 [(set_attr "type" "call_no_delay_slot")
6312 (set_attr "length" "3")])
6314 (define_expand "call_value"
6315 ;; Note that this expression is not used for generating RTL.
6316 ;; All the RTL is generated explicitly below.
6317 [(set (match_operand 0 "register_operand" "=rf")
6318 (call (match_operand 1 "" "")
6319 (match_operand 4 "" "")))]
6320 ;; operand 2 is stack_size_rtx
6321 ;; operand 3 is next_arg_register
6327 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6329 fn_rtx = operands[1];
6332 gen_rtx_SET (VOIDmode, operands[0],
6333 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6334 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6336 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6341 (define_insn "*call_value_address_sp32"
6342 [(set (match_operand 0 "" "=rf")
6343 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6344 (match_operand 2 "" "")))
6345 (clobber (reg:SI O7_REG))]
6346 ;;- Do not use operand 2 for most machines.
6349 [(set_attr "type" "call")])
6351 (define_insn "*call_value_symbolic_sp32"
6352 [(set (match_operand 0 "" "=rf")
6353 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6354 (match_operand 2 "" "")))
6355 (clobber (reg:SI O7_REG))]
6356 ;;- Do not use operand 2 for most machines.
6359 [(set_attr "type" "call")])
6361 (define_insn "*call_value_address_sp64"
6362 [(set (match_operand 0 "" "")
6363 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6364 (match_operand 2 "" "")))
6365 (clobber (reg:DI O7_REG))]
6366 ;;- Do not use operand 2 for most machines.
6369 [(set_attr "type" "call")])
6371 (define_insn "*call_value_symbolic_sp64"
6372 [(set (match_operand 0 "" "")
6373 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6374 (match_operand 2 "" "")))
6375 (clobber (reg:DI O7_REG))]
6376 ;;- Do not use operand 2 for most machines.
6379 [(set_attr "type" "call")])
6381 (define_expand "untyped_call"
6382 [(parallel [(call (match_operand 0 "" "")
6384 (match_operand:BLK 1 "memory_operand" "")
6385 (match_operand 2 "" "")])]
6388 rtx valreg1 = gen_rtx_REG (DImode, 8);
6389 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6390 rtx result = operands[1];
6392 /* Pass constm1 to indicate that it may expect a structure value, but
6393 we don't know what size it is. */
6394 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6396 /* Save the function value registers. */
6397 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6398 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6401 /* The optimizer does not know that the call sets the function value
6402 registers we stored in the result block. We avoid problems by
6403 claiming that all hard registers are used and clobbered at this
6405 emit_insn (gen_blockage ());
6410 ;; Tail call instructions.
6412 (define_expand "sibcall"
6413 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6418 (define_insn "*sibcall_symbolic_sp32"
6419 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6420 (match_operand 1 "" ""))
6423 "* return output_sibcall(insn, operands[0]);"
6424 [(set_attr "type" "sibcall")])
6426 (define_insn "*sibcall_symbolic_sp64"
6427 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6428 (match_operand 1 "" ""))
6431 "* return output_sibcall(insn, operands[0]);"
6432 [(set_attr "type" "sibcall")])
6434 (define_expand "sibcall_value"
6435 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6436 (call (match_operand 1 "" "") (const_int 0)))
6441 (define_insn "*sibcall_value_symbolic_sp32"
6442 [(set (match_operand 0 "" "=rf")
6443 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6444 (match_operand 2 "" "")))
6447 "* return output_sibcall(insn, operands[1]);"
6448 [(set_attr "type" "sibcall")])
6450 (define_insn "*sibcall_value_symbolic_sp64"
6451 [(set (match_operand 0 "" "")
6452 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6453 (match_operand 2 "" "")))
6456 "* return output_sibcall(insn, operands[1]);"
6457 [(set_attr "type" "sibcall")])
6460 ;; Special instructions.
6462 (define_expand "prologue"
6467 sparc_flat_expand_prologue ();
6469 sparc_expand_prologue ();
6473 ;; The "register window save" insn is modelled as follows. The dwarf2
6474 ;; information is manually added in emit_window_save.
6476 (define_insn "window_save"
6478 [(match_operand 0 "arith_operand" "rI")]
6481 "save\t%%sp, %0, %%sp"
6482 [(set_attr "type" "savew")])
6484 (define_expand "epilogue"
6489 sparc_flat_expand_epilogue (false);
6491 sparc_expand_epilogue (false);
6494 (define_expand "sibcall_epilogue"
6499 sparc_flat_expand_epilogue (false);
6501 sparc_expand_epilogue (false);
6505 (define_expand "eh_return"
6506 [(use (match_operand 0 "general_operand" ""))]
6509 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6510 emit_jump_insn (gen_eh_return_internal ());
6515 (define_insn_and_split "eh_return_internal"
6519 "epilogue_completed"
6523 sparc_flat_expand_epilogue (true);
6525 sparc_expand_epilogue (true);
6528 (define_expand "return"
6530 "sparc_can_use_return_insn_p ()"
6533 (define_insn "*return_internal"
6536 "* return output_return (insn);"
6537 [(set_attr "type" "return")
6538 (set (attr "length")
6539 (cond [(eq_attr "calls_eh_return" "true")
6540 (if_then_else (eq_attr "delayed_branch" "true")
6541 (if_then_else (ior (eq_attr "isa" "v9")
6542 (eq_attr "flat" "true"))
6545 (if_then_else (eq_attr "flat" "true")
6548 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6549 (if_then_else (eq_attr "empty_delay_slot" "true")
6552 (eq_attr "empty_delay_slot" "true")
6553 (if_then_else (eq_attr "delayed_branch" "true")
6558 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6559 ;; all of memory. This blocks insns from being moved across this point.
6561 (define_insn "blockage"
6562 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6565 [(set_attr "length" "0")])
6567 ;; Do not schedule instructions accessing memory before this point.
6569 (define_expand "frame_blockage"
6571 (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
6574 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6575 MEM_VOLATILE_P (operands[0]) = 1;
6576 operands[1] = stack_pointer_rtx;
6579 (define_insn "*frame_blockage<P:mode>"
6580 [(set (match_operand:BLK 0 "" "")
6581 (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
6584 [(set_attr "length" "0")])
6586 (define_expand "probe_stack"
6587 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6591 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6594 (define_insn "probe_stack_range<P:mode>"
6595 [(set (match_operand:P 0 "register_operand" "=r")
6596 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6597 (match_operand:P 2 "register_operand" "r")]
6598 UNSPECV_PROBE_STACK_RANGE))]
6600 "* return output_probe_stack_range (operands[0], operands[2]);"
6601 [(set_attr "type" "multi")])
6603 ;; Prepare to return any type including a structure value.
6605 (define_expand "untyped_return"
6606 [(match_operand:BLK 0 "memory_operand" "")
6607 (match_operand 1 "" "")]
6610 rtx valreg1 = gen_rtx_REG (DImode, 24);
6611 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6612 rtx result = operands[0];
6614 if (! TARGET_ARCH64)
6616 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6617 rtx value = gen_reg_rtx (SImode);
6619 /* Fetch the instruction where we will return to and see if it's an unimp
6620 instruction (the most significant 10 bits will be zero). If so,
6621 update the return address to skip the unimp instruction. */
6622 emit_move_insn (value,
6623 gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8)));
6624 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6625 emit_insn (gen_update_return (rtnreg, value));
6628 /* Reload the function value registers. */
6629 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6630 emit_move_insn (valreg2,
6631 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6633 /* Put USE insns before the return. */
6637 /* Construct the return. */
6638 expand_naked_return ();
6643 ;; Adjust the return address conditionally. If the value of op1 is equal
6644 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6645 ;; This is technically *half* the check required by the 32-bit SPARC
6646 ;; psABI. This check only ensures that an "unimp" insn was written by
6647 ;; the caller, but doesn't check to see if the expected size matches
6648 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6649 ;; only used by the above code "untyped_return".
6651 (define_insn "update_return"
6652 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6653 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6656 if (flag_delayed_branch)
6657 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6659 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6661 [(set (attr "type") (const_string "multi"))
6662 (set (attr "length")
6663 (if_then_else (eq_attr "delayed_branch" "true")
6672 (define_expand "indirect_jump"
6673 [(set (pc) (match_operand 0 "address_operand" "p"))]
6677 (define_insn "*branch_sp32"
6678 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6681 [(set_attr "type" "uncond_branch")])
6683 (define_insn "*branch_sp64"
6684 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6687 [(set_attr "type" "uncond_branch")])
6689 (define_expand "save_stack_nonlocal"
6690 [(set (match_operand 0 "memory_operand" "")
6691 (match_operand 1 "register_operand" ""))
6692 (set (match_dup 2) (match_dup 3))]
6695 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6696 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6697 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6700 (define_expand "restore_stack_nonlocal"
6701 [(set (match_operand 0 "register_operand" "")
6702 (match_operand 1 "memory_operand" ""))]
6705 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6708 (define_expand "nonlocal_goto"
6709 [(match_operand 0 "general_operand" "")
6710 (match_operand 1 "general_operand" "")
6711 (match_operand 2 "memory_operand" "")
6712 (match_operand 3 "memory_operand" "")]
6715 rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6716 rtx r_label = copy_to_reg (operands[1]);
6717 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6718 rtx r_fp = operands[3];
6719 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6721 /* We need to flush all the register windows so that their contents will
6722 be re-synchronized by the restore insn of the target function. */
6724 emit_insn (gen_flush_register_windows ());
6726 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6727 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6729 /* Restore frame pointer for containing function. */
6730 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6731 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6732 emit_move_insn (i7, r_i7);
6734 /* USE of hard_frame_pointer_rtx added for consistency;
6735 not clear if really needed. */
6736 emit_use (hard_frame_pointer_rtx);
6737 emit_use (stack_pointer_rtx);
6740 emit_jump_insn (gen_indirect_jump (r_label));
6745 (define_expand "builtin_setjmp_receiver"
6746 [(label_ref (match_operand 0 "" ""))]
6749 load_got_register ();
6753 ;; Special insn to flush register windows.
6755 (define_insn "flush_register_windows"
6756 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6758 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6759 [(set_attr "type" "flushw")])
6761 ;; Special pattern for the FLUSH instruction.
6763 (define_insn "flush<P:mode>"
6764 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6766 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6767 [(set_attr "type" "iflush")])
6769 ;; Special insns to load and store the 32-bit FP Status Register.
6771 (define_insn "ldfsr"
6772 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)]
6775 [(set_attr "type" "load")])
6777 (define_insn "stfsr"
6778 [(set (match_operand:SI 0 "memory_operand" "=m")
6779 (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))]
6782 [(set_attr "type" "store")])
6785 ;; Find first set instructions.
6787 ;; The scan instruction searches from the most significant bit while ffs
6788 ;; searches from the least significant bit. The bit index and treatment of
6789 ;; zero also differ. It takes at least 7 instructions to get the proper
6790 ;; result. Here is an obvious 8 instruction sequence.
6793 (define_insn "ffssi2"
6794 [(set (match_operand:SI 0 "register_operand" "=&r")
6795 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6796 (clobber (match_scratch:SI 2 "=&r"))]
6797 "TARGET_SPARCLITE || TARGET_SPARCLET"
6799 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";
6801 [(set_attr "type" "multi")
6802 (set_attr "length" "8")])
6804 (define_expand "popcountdi2"
6805 [(set (match_operand:DI 0 "register_operand" "")
6806 (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6809 if (! TARGET_ARCH64)
6811 emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6816 (define_insn "*popcountdi_sp64"
6817 [(set (match_operand:DI 0 "register_operand" "=r")
6818 (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6819 "TARGET_POPC && TARGET_ARCH64"
6822 (define_insn "popcountdi_v8plus"
6823 [(set (match_operand:DI 0 "register_operand" "=r")
6824 (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6825 (clobber (match_scratch:SI 2 "=&h"))]
6826 "TARGET_POPC && ! TARGET_ARCH64"
6828 if (sparc_check_64 (operands[1], insn) <= 0)
6829 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6830 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6832 [(set_attr "type" "multi")
6833 (set_attr "length" "5")])
6835 (define_expand "popcountsi2"
6837 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6838 (set (match_operand:SI 0 "register_operand" "")
6839 (truncate:SI (popcount:DI (match_dup 2))))]
6842 if (! TARGET_ARCH64)
6844 emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6848 operands[2] = gen_reg_rtx (DImode);
6851 (define_insn "*popcountsi_sp64"
6852 [(set (match_operand:SI 0 "register_operand" "=r")
6854 (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6855 "TARGET_POPC && TARGET_ARCH64"
6858 (define_insn "popcountsi_v8plus"
6859 [(set (match_operand:SI 0 "register_operand" "=r")
6860 (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6861 "TARGET_POPC && ! TARGET_ARCH64"
6863 if (sparc_check_64 (operands[1], insn) <= 0)
6864 output_asm_insn ("srl\t%1, 0, %1", operands);
6865 return "popc\t%1, %0";
6867 [(set_attr "type" "multi")
6868 (set_attr "length" "2")])
6870 (define_expand "clzdi2"
6871 [(set (match_operand:DI 0 "register_operand" "")
6872 (clz:DI (match_operand:DI 1 "register_operand" "")))]
6875 if (! TARGET_ARCH64)
6877 emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6882 (define_insn "*clzdi_sp64"
6883 [(set (match_operand:DI 0 "register_operand" "=r")
6884 (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6885 "TARGET_VIS3 && TARGET_ARCH64"
6888 (define_insn "clzdi_v8plus"
6889 [(set (match_operand:DI 0 "register_operand" "=r")
6890 (clz:DI (match_operand:DI 1 "register_operand" "r")))
6891 (clobber (match_scratch:SI 2 "=&h"))]
6892 "TARGET_VIS3 && ! TARGET_ARCH64"
6894 if (sparc_check_64 (operands[1], insn) <= 0)
6895 output_asm_insn ("srl\t%L1, 0, %L1", operands);
6896 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6898 [(set_attr "type" "multi")
6899 (set_attr "length" "5")])
6901 (define_expand "clzsi2"
6903 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6905 (truncate:SI (clz:DI (match_dup 2))))
6906 (set (match_operand:SI 0 "register_operand" "")
6907 (minus:SI (match_dup 3) (const_int 32)))]
6910 if (! TARGET_ARCH64)
6912 emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6917 operands[2] = gen_reg_rtx (DImode);
6918 operands[3] = gen_reg_rtx (SImode);
6922 (define_insn "*clzsi_sp64"
6923 [(set (match_operand:SI 0 "register_operand" "=r")
6925 (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6926 "TARGET_VIS3 && TARGET_ARCH64"
6929 (define_insn "clzsi_v8plus"
6930 [(set (match_operand:SI 0 "register_operand" "=r")
6931 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6932 "TARGET_VIS3 && ! TARGET_ARCH64"
6934 if (sparc_check_64 (operands[1], insn) <= 0)
6935 output_asm_insn ("srl\t%1, 0, %1", operands);
6936 return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6938 [(set_attr "type" "multi")
6939 (set_attr "length" "3")])
6942 ;; Peepholes go at the end.
6944 ;; Optimize consecutive loads or stores into ldd and std when possible.
6945 ;; The conditions in which we do this are very restricted and are
6946 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6949 [(set (match_operand:SI 0 "memory_operand" "")
6951 (set (match_operand:SI 1 "memory_operand" "")
6954 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6955 [(set (match_dup 0) (const_int 0))]
6957 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode);
6961 [(set (match_operand:SI 0 "memory_operand" "")
6963 (set (match_operand:SI 1 "memory_operand" "")
6966 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6967 [(set (match_dup 1) (const_int 0))]
6969 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode);
6973 [(set (match_operand:SI 0 "register_operand" "")
6974 (match_operand:SI 1 "memory_operand" ""))
6975 (set (match_operand:SI 2 "register_operand" "")
6976 (match_operand:SI 3 "memory_operand" ""))]
6977 "registers_ok_for_ldd_peep (operands[0], operands[2])
6978 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6979 [(set (match_dup 0) (match_dup 1))]
6981 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode);
6982 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6986 [(set (match_operand:SI 0 "memory_operand" "")
6987 (match_operand:SI 1 "register_operand" ""))
6988 (set (match_operand:SI 2 "memory_operand" "")
6989 (match_operand:SI 3 "register_operand" ""))]
6990 "registers_ok_for_ldd_peep (operands[1], operands[3])
6991 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6992 [(set (match_dup 0) (match_dup 1))]
6994 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode);
6995 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
6999 [(set (match_operand:SF 0 "register_operand" "")
7000 (match_operand:SF 1 "memory_operand" ""))
7001 (set (match_operand:SF 2 "register_operand" "")
7002 (match_operand:SF 3 "memory_operand" ""))]
7003 "registers_ok_for_ldd_peep (operands[0], operands[2])
7004 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7005 [(set (match_dup 0) (match_dup 1))]
7007 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode);
7008 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));
7012 [(set (match_operand:SF 0 "memory_operand" "")
7013 (match_operand:SF 1 "register_operand" ""))
7014 (set (match_operand:SF 2 "memory_operand" "")
7015 (match_operand:SF 3 "register_operand" ""))]
7016 "registers_ok_for_ldd_peep (operands[1], operands[3])
7017 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7018 [(set (match_dup 0) (match_dup 1))]
7020 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode);
7021 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));
7025 [(set (match_operand:SI 0 "register_operand" "")
7026 (match_operand:SI 1 "memory_operand" ""))
7027 (set (match_operand:SI 2 "register_operand" "")
7028 (match_operand:SI 3 "memory_operand" ""))]
7029 "registers_ok_for_ldd_peep (operands[2], operands[0])
7030 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7031 [(set (match_dup 2) (match_dup 3))]
7033 operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode);
7034 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));
7038 [(set (match_operand:SI 0 "memory_operand" "")
7039 (match_operand:SI 1 "register_operand" ""))
7040 (set (match_operand:SI 2 "memory_operand" "")
7041 (match_operand:SI 3 "register_operand" ""))]
7042 "registers_ok_for_ldd_peep (operands[3], operands[1])
7043 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7044 [(set (match_dup 2) (match_dup 3))]
7046 operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DImode);
7047 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7051 [(set (match_operand:SF 0 "register_operand" "")
7052 (match_operand:SF 1 "memory_operand" ""))
7053 (set (match_operand:SF 2 "register_operand" "")
7054 (match_operand:SF 3 "memory_operand" ""))]
7055 "registers_ok_for_ldd_peep (operands[2], operands[0])
7056 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7057 [(set (match_dup 2) (match_dup 3))]
7059 operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode);
7060 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));
7064 [(set (match_operand:SF 0 "memory_operand" "")
7065 (match_operand:SF 1 "register_operand" ""))
7066 (set (match_operand:SF 2 "memory_operand" "")
7067 (match_operand:SF 3 "register_operand" ""))]
7068 "registers_ok_for_ldd_peep (operands[3], operands[1])
7069 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7070 [(set (match_dup 2) (match_dup 3))]
7072 operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode);
7073 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));
7076 ;; Optimize the case of following a reg-reg move with a test
7077 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7078 ;; This can result from a float to fix conversion.
7081 [(set (match_operand:SI 0 "register_operand" "")
7082 (match_operand:SI 1 "register_operand" ""))
7083 (set (reg:CC CC_REG)
7084 (compare:CC (match_operand:SI 2 "register_operand" "")
7086 "(rtx_equal_p (operands[2], operands[0])
7087 || rtx_equal_p (operands[2], operands[1]))
7088 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7089 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7090 [(parallel [(set (match_dup 0) (match_dup 1))
7091 (set (reg:CC CC_REG)
7092 (compare:CC (match_dup 1) (const_int 0)))])]
7096 [(set (match_operand:DI 0 "register_operand" "")
7097 (match_operand:DI 1 "register_operand" ""))
7098 (set (reg:CCX CC_REG)
7099 (compare:CCX (match_operand:DI 2 "register_operand" "")
7102 && (rtx_equal_p (operands[2], operands[0])
7103 || rtx_equal_p (operands[2], operands[1]))
7104 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7105 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7106 [(parallel [(set (match_dup 0) (match_dup 1))
7107 (set (reg:CCX CC_REG)
7108 (compare:CCX (match_dup 1) (const_int 0)))])]
7112 ;; Prefetch instructions.
7114 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7115 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7116 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7118 (define_expand "prefetch"
7119 [(match_operand 0 "address_operand" "")
7120 (match_operand 1 "const_int_operand" "")
7121 (match_operand 2 "const_int_operand" "")]
7125 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7127 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7131 (define_insn "prefetch_64"
7132 [(prefetch (match_operand:DI 0 "address_operand" "p")
7133 (match_operand:DI 1 "const_int_operand" "n")
7134 (match_operand:DI 2 "const_int_operand" "n"))]
7137 static const char * const prefetch_instr[2][2] = {
7139 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7140 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7143 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7144 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7147 int read_or_write = INTVAL (operands[1]);
7148 int locality = INTVAL (operands[2]);
7150 gcc_assert (read_or_write == 0 || read_or_write == 1);
7151 gcc_assert (locality >= 0 && locality < 4);
7152 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7154 [(set_attr "type" "load")])
7156 (define_insn "prefetch_32"
7157 [(prefetch (match_operand:SI 0 "address_operand" "p")
7158 (match_operand:SI 1 "const_int_operand" "n")
7159 (match_operand:SI 2 "const_int_operand" "n"))]
7162 static const char * const prefetch_instr[2][2] = {
7164 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7165 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7168 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7169 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7172 int read_or_write = INTVAL (operands[1]);
7173 int locality = INTVAL (operands[2]);
7175 gcc_assert (read_or_write == 0 || read_or_write == 1);
7176 gcc_assert (locality >= 0 && locality < 4);
7177 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7179 [(set_attr "type" "load")])
7182 ;; Trap instructions.
7185 [(trap_if (const_int 1) (const_int 5))]
7188 [(set_attr "type" "trap")])
7190 (define_expand "ctrapsi4"
7191 [(trap_if (match_operator 0 "noov_compare_operator"
7192 [(match_operand:SI 1 "compare_operand" "")
7193 (match_operand:SI 2 "arith_operand" "")])
7194 (match_operand 3 "arith_operand"))]
7196 "operands[1] = gen_compare_reg (operands[0]);
7197 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7199 operands[2] = const0_rtx;")
7201 (define_expand "ctrapdi4"
7202 [(trap_if (match_operator 0 "noov_compare_operator"
7203 [(match_operand:DI 1 "compare_operand" "")
7204 (match_operand:DI 2 "arith_operand" "")])
7205 (match_operand 3 "arith_operand"))]
7207 "operands[1] = gen_compare_reg (operands[0]);
7208 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7210 operands[2] = const0_rtx;")
7214 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7215 (match_operand:SI 1 "arith_operand" "rM"))]
7219 return "t%C0\t%%icc, %1";
7223 [(set_attr "type" "trap")])
7226 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7227 (match_operand:SI 1 "arith_operand" "rM"))]
7230 [(set_attr "type" "trap")])
7233 ;; TLS support instructions.
7235 (define_insn "tgd_hi22"
7236 [(set (match_operand:SI 0 "register_operand" "=r")
7237 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7240 "sethi\\t%%tgd_hi22(%a1), %0")
7242 (define_insn "tgd_lo10"
7243 [(set (match_operand:SI 0 "register_operand" "=r")
7244 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7245 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7248 "add\\t%1, %%tgd_lo10(%a2), %0")
7250 (define_insn "tgd_add32"
7251 [(set (match_operand:SI 0 "register_operand" "=r")
7252 (plus:SI (match_operand:SI 1 "register_operand" "r")
7253 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7254 (match_operand 3 "tgd_symbolic_operand" "")]
7256 "TARGET_TLS && TARGET_ARCH32"
7257 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7259 (define_insn "tgd_add64"
7260 [(set (match_operand:DI 0 "register_operand" "=r")
7261 (plus:DI (match_operand:DI 1 "register_operand" "r")
7262 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7263 (match_operand 3 "tgd_symbolic_operand" "")]
7265 "TARGET_TLS && TARGET_ARCH64"
7266 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7268 (define_insn "tgd_call32"
7269 [(set (match_operand 0 "register_operand" "=r")
7270 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7271 (match_operand 2 "tgd_symbolic_operand" "")]
7273 (match_operand 3 "" "")))
7274 (clobber (reg:SI O7_REG))]
7275 "TARGET_TLS && TARGET_ARCH32"
7276 "call\t%a1, %%tgd_call(%a2)%#"
7277 [(set_attr "type" "call")])
7279 (define_insn "tgd_call64"
7280 [(set (match_operand 0 "register_operand" "=r")
7281 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7282 (match_operand 2 "tgd_symbolic_operand" "")]
7284 (match_operand 3 "" "")))
7285 (clobber (reg:DI O7_REG))]
7286 "TARGET_TLS && TARGET_ARCH64"
7287 "call\t%a1, %%tgd_call(%a2)%#"
7288 [(set_attr "type" "call")])
7290 (define_insn "tldm_hi22"
7291 [(set (match_operand:SI 0 "register_operand" "=r")
7292 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7294 "sethi\\t%%tldm_hi22(%&), %0")
7296 (define_insn "tldm_lo10"
7297 [(set (match_operand:SI 0 "register_operand" "=r")
7298 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7299 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7301 "add\\t%1, %%tldm_lo10(%&), %0")
7303 (define_insn "tldm_add32"
7304 [(set (match_operand:SI 0 "register_operand" "=r")
7305 (plus:SI (match_operand:SI 1 "register_operand" "r")
7306 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7308 "TARGET_TLS && TARGET_ARCH32"
7309 "add\\t%1, %2, %0, %%tldm_add(%&)")
7311 (define_insn "tldm_add64"
7312 [(set (match_operand:DI 0 "register_operand" "=r")
7313 (plus:DI (match_operand:DI 1 "register_operand" "r")
7314 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7316 "TARGET_TLS && TARGET_ARCH64"
7317 "add\\t%1, %2, %0, %%tldm_add(%&)")
7319 (define_insn "tldm_call32"
7320 [(set (match_operand 0 "register_operand" "=r")
7321 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7323 (match_operand 2 "" "")))
7324 (clobber (reg:SI O7_REG))]
7325 "TARGET_TLS && TARGET_ARCH32"
7326 "call\t%a1, %%tldm_call(%&)%#"
7327 [(set_attr "type" "call")])
7329 (define_insn "tldm_call64"
7330 [(set (match_operand 0 "register_operand" "=r")
7331 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7333 (match_operand 2 "" "")))
7334 (clobber (reg:DI O7_REG))]
7335 "TARGET_TLS && TARGET_ARCH64"
7336 "call\t%a1, %%tldm_call(%&)%#"
7337 [(set_attr "type" "call")])
7339 (define_insn "tldo_hix22"
7340 [(set (match_operand:SI 0 "register_operand" "=r")
7341 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7344 "sethi\\t%%tldo_hix22(%a1), %0")
7346 (define_insn "tldo_lox10"
7347 [(set (match_operand:SI 0 "register_operand" "=r")
7348 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7349 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7352 "xor\\t%1, %%tldo_lox10(%a2), %0")
7354 (define_insn "tldo_add32"
7355 [(set (match_operand:SI 0 "register_operand" "=r")
7356 (plus:SI (match_operand:SI 1 "register_operand" "r")
7357 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7358 (match_operand 3 "tld_symbolic_operand" "")]
7360 "TARGET_TLS && TARGET_ARCH32"
7361 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7363 (define_insn "tldo_add64"
7364 [(set (match_operand:DI 0 "register_operand" "=r")
7365 (plus:DI (match_operand:DI 1 "register_operand" "r")
7366 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7367 (match_operand 3 "tld_symbolic_operand" "")]
7369 "TARGET_TLS && TARGET_ARCH64"
7370 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7372 (define_insn "tie_hi22"
7373 [(set (match_operand:SI 0 "register_operand" "=r")
7374 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7377 "sethi\\t%%tie_hi22(%a1), %0")
7379 (define_insn "tie_lo10"
7380 [(set (match_operand:SI 0 "register_operand" "=r")
7381 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7382 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7385 "add\\t%1, %%tie_lo10(%a2), %0")
7387 (define_insn "tie_ld32"
7388 [(set (match_operand:SI 0 "register_operand" "=r")
7389 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7390 (match_operand:SI 2 "register_operand" "r")
7391 (match_operand 3 "tie_symbolic_operand" "")]
7393 "TARGET_TLS && TARGET_ARCH32"
7394 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7395 [(set_attr "type" "load")])
7397 (define_insn "tie_ld64"
7398 [(set (match_operand:DI 0 "register_operand" "=r")
7399 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7400 (match_operand:SI 2 "register_operand" "r")
7401 (match_operand 3 "tie_symbolic_operand" "")]
7403 "TARGET_TLS && TARGET_ARCH64"
7404 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7405 [(set_attr "type" "load")])
7407 (define_insn "tie_add32"
7408 [(set (match_operand:SI 0 "register_operand" "=r")
7409 (plus:SI (match_operand:SI 1 "register_operand" "r")
7410 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7411 (match_operand 3 "tie_symbolic_operand" "")]
7413 "TARGET_SUN_TLS && TARGET_ARCH32"
7414 "add\\t%1, %2, %0, %%tie_add(%a3)")
7416 (define_insn "tie_add64"
7417 [(set (match_operand:DI 0 "register_operand" "=r")
7418 (plus:DI (match_operand:DI 1 "register_operand" "r")
7419 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7420 (match_operand 3 "tie_symbolic_operand" "")]
7422 "TARGET_SUN_TLS && TARGET_ARCH64"
7423 "add\\t%1, %2, %0, %%tie_add(%a3)")
7425 (define_insn "tle_hix22_sp32"
7426 [(set (match_operand:SI 0 "register_operand" "=r")
7427 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7429 "TARGET_TLS && TARGET_ARCH32"
7430 "sethi\\t%%tle_hix22(%a1), %0")
7432 (define_insn "tle_lox10_sp32"
7433 [(set (match_operand:SI 0 "register_operand" "=r")
7434 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7435 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7437 "TARGET_TLS && TARGET_ARCH32"
7438 "xor\\t%1, %%tle_lox10(%a2), %0")
7440 (define_insn "tle_hix22_sp64"
7441 [(set (match_operand:DI 0 "register_operand" "=r")
7442 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7444 "TARGET_TLS && TARGET_ARCH64"
7445 "sethi\\t%%tle_hix22(%a1), %0")
7447 (define_insn "tle_lox10_sp64"
7448 [(set (match_operand:DI 0 "register_operand" "=r")
7449 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7450 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7452 "TARGET_TLS && TARGET_ARCH64"
7453 "xor\\t%1, %%tle_lox10(%a2), %0")
7455 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7456 (define_insn "*tldo_ldub_sp32"
7457 [(set (match_operand:QI 0 "register_operand" "=r")
7458 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7459 (match_operand 3 "tld_symbolic_operand" "")]
7461 (match_operand:SI 1 "register_operand" "r"))))]
7462 "TARGET_TLS && TARGET_ARCH32"
7463 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7464 [(set_attr "type" "load")
7465 (set_attr "us3load_type" "3cycle")])
7467 (define_insn "*tldo_ldub1_sp32"
7468 [(set (match_operand:HI 0 "register_operand" "=r")
7469 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7470 (match_operand 3 "tld_symbolic_operand" "")]
7472 (match_operand:SI 1 "register_operand" "r")))))]
7473 "TARGET_TLS && TARGET_ARCH32"
7474 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7475 [(set_attr "type" "load")
7476 (set_attr "us3load_type" "3cycle")])
7478 (define_insn "*tldo_ldub2_sp32"
7479 [(set (match_operand:SI 0 "register_operand" "=r")
7480 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7481 (match_operand 3 "tld_symbolic_operand" "")]
7483 (match_operand:SI 1 "register_operand" "r")))))]
7484 "TARGET_TLS && TARGET_ARCH32"
7485 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7486 [(set_attr "type" "load")
7487 (set_attr "us3load_type" "3cycle")])
7489 (define_insn "*tldo_ldsb1_sp32"
7490 [(set (match_operand:HI 0 "register_operand" "=r")
7491 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7492 (match_operand 3 "tld_symbolic_operand" "")]
7494 (match_operand:SI 1 "register_operand" "r")))))]
7495 "TARGET_TLS && TARGET_ARCH32"
7496 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7497 [(set_attr "type" "sload")
7498 (set_attr "us3load_type" "3cycle")])
7500 (define_insn "*tldo_ldsb2_sp32"
7501 [(set (match_operand:SI 0 "register_operand" "=r")
7502 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7503 (match_operand 3 "tld_symbolic_operand" "")]
7505 (match_operand:SI 1 "register_operand" "r")))))]
7506 "TARGET_TLS && TARGET_ARCH32"
7507 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7508 [(set_attr "type" "sload")
7509 (set_attr "us3load_type" "3cycle")])
7511 (define_insn "*tldo_ldub_sp64"
7512 [(set (match_operand:QI 0 "register_operand" "=r")
7513 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7514 (match_operand 3 "tld_symbolic_operand" "")]
7516 (match_operand:DI 1 "register_operand" "r"))))]
7517 "TARGET_TLS && TARGET_ARCH64"
7518 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7519 [(set_attr "type" "load")
7520 (set_attr "us3load_type" "3cycle")])
7522 (define_insn "*tldo_ldub1_sp64"
7523 [(set (match_operand:HI 0 "register_operand" "=r")
7524 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7525 (match_operand 3 "tld_symbolic_operand" "")]
7527 (match_operand:DI 1 "register_operand" "r")))))]
7528 "TARGET_TLS && TARGET_ARCH64"
7529 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7530 [(set_attr "type" "load")
7531 (set_attr "us3load_type" "3cycle")])
7533 (define_insn "*tldo_ldub2_sp64"
7534 [(set (match_operand:SI 0 "register_operand" "=r")
7535 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7536 (match_operand 3 "tld_symbolic_operand" "")]
7538 (match_operand:DI 1 "register_operand" "r")))))]
7539 "TARGET_TLS && TARGET_ARCH64"
7540 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7541 [(set_attr "type" "load")
7542 (set_attr "us3load_type" "3cycle")])
7544 (define_insn "*tldo_ldub3_sp64"
7545 [(set (match_operand:DI 0 "register_operand" "=r")
7546 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7547 (match_operand 3 "tld_symbolic_operand" "")]
7549 (match_operand:DI 1 "register_operand" "r")))))]
7550 "TARGET_TLS && TARGET_ARCH64"
7551 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7552 [(set_attr "type" "load")
7553 (set_attr "us3load_type" "3cycle")])
7555 (define_insn "*tldo_ldsb1_sp64"
7556 [(set (match_operand:HI 0 "register_operand" "=r")
7557 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7558 (match_operand 3 "tld_symbolic_operand" "")]
7560 (match_operand:DI 1 "register_operand" "r")))))]
7561 "TARGET_TLS && TARGET_ARCH64"
7562 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7563 [(set_attr "type" "sload")
7564 (set_attr "us3load_type" "3cycle")])
7566 (define_insn "*tldo_ldsb2_sp64"
7567 [(set (match_operand:SI 0 "register_operand" "=r")
7568 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7569 (match_operand 3 "tld_symbolic_operand" "")]
7571 (match_operand:DI 1 "register_operand" "r")))))]
7572 "TARGET_TLS && TARGET_ARCH64"
7573 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7574 [(set_attr "type" "sload")
7575 (set_attr "us3load_type" "3cycle")])
7577 (define_insn "*tldo_ldsb3_sp64"
7578 [(set (match_operand:DI 0 "register_operand" "=r")
7579 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7580 (match_operand 3 "tld_symbolic_operand" "")]
7582 (match_operand:DI 1 "register_operand" "r")))))]
7583 "TARGET_TLS && TARGET_ARCH64"
7584 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7585 [(set_attr "type" "sload")
7586 (set_attr "us3load_type" "3cycle")])
7588 (define_insn "*tldo_lduh_sp32"
7589 [(set (match_operand:HI 0 "register_operand" "=r")
7590 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7591 (match_operand 3 "tld_symbolic_operand" "")]
7593 (match_operand:SI 1 "register_operand" "r"))))]
7594 "TARGET_TLS && TARGET_ARCH32"
7595 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7596 [(set_attr "type" "load")
7597 (set_attr "us3load_type" "3cycle")])
7599 (define_insn "*tldo_lduh1_sp32"
7600 [(set (match_operand:SI 0 "register_operand" "=r")
7601 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7602 (match_operand 3 "tld_symbolic_operand" "")]
7604 (match_operand:SI 1 "register_operand" "r")))))]
7605 "TARGET_TLS && TARGET_ARCH32"
7606 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7607 [(set_attr "type" "load")
7608 (set_attr "us3load_type" "3cycle")])
7610 (define_insn "*tldo_ldsh1_sp32"
7611 [(set (match_operand:SI 0 "register_operand" "=r")
7612 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7613 (match_operand 3 "tld_symbolic_operand" "")]
7615 (match_operand:SI 1 "register_operand" "r")))))]
7616 "TARGET_TLS && TARGET_ARCH32"
7617 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7618 [(set_attr "type" "sload")
7619 (set_attr "us3load_type" "3cycle")])
7621 (define_insn "*tldo_lduh_sp64"
7622 [(set (match_operand:HI 0 "register_operand" "=r")
7623 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7624 (match_operand 3 "tld_symbolic_operand" "")]
7626 (match_operand:DI 1 "register_operand" "r"))))]
7627 "TARGET_TLS && TARGET_ARCH64"
7628 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7629 [(set_attr "type" "load")
7630 (set_attr "us3load_type" "3cycle")])
7632 (define_insn "*tldo_lduh1_sp64"
7633 [(set (match_operand:SI 0 "register_operand" "=r")
7634 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7635 (match_operand 3 "tld_symbolic_operand" "")]
7637 (match_operand:DI 1 "register_operand" "r")))))]
7638 "TARGET_TLS && TARGET_ARCH64"
7639 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7640 [(set_attr "type" "load")
7641 (set_attr "us3load_type" "3cycle")])
7643 (define_insn "*tldo_lduh2_sp64"
7644 [(set (match_operand:DI 0 "register_operand" "=r")
7645 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7646 (match_operand 3 "tld_symbolic_operand" "")]
7648 (match_operand:DI 1 "register_operand" "r")))))]
7649 "TARGET_TLS && TARGET_ARCH64"
7650 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7651 [(set_attr "type" "load")
7652 (set_attr "us3load_type" "3cycle")])
7654 (define_insn "*tldo_ldsh1_sp64"
7655 [(set (match_operand:SI 0 "register_operand" "=r")
7656 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7657 (match_operand 3 "tld_symbolic_operand" "")]
7659 (match_operand:DI 1 "register_operand" "r")))))]
7660 "TARGET_TLS && TARGET_ARCH64"
7661 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7662 [(set_attr "type" "sload")
7663 (set_attr "us3load_type" "3cycle")])
7665 (define_insn "*tldo_ldsh2_sp64"
7666 [(set (match_operand:DI 0 "register_operand" "=r")
7667 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7668 (match_operand 3 "tld_symbolic_operand" "")]
7670 (match_operand:DI 1 "register_operand" "r")))))]
7671 "TARGET_TLS && TARGET_ARCH64"
7672 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7673 [(set_attr "type" "sload")
7674 (set_attr "us3load_type" "3cycle")])
7676 (define_insn "*tldo_lduw_sp32"
7677 [(set (match_operand:SI 0 "register_operand" "=r")
7678 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7679 (match_operand 3 "tld_symbolic_operand" "")]
7681 (match_operand:SI 1 "register_operand" "r"))))]
7682 "TARGET_TLS && TARGET_ARCH32"
7683 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7684 [(set_attr "type" "load")])
7686 (define_insn "*tldo_lduw_sp64"
7687 [(set (match_operand:SI 0 "register_operand" "=r")
7688 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7689 (match_operand 3 "tld_symbolic_operand" "")]
7691 (match_operand:DI 1 "register_operand" "r"))))]
7692 "TARGET_TLS && TARGET_ARCH64"
7693 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7694 [(set_attr "type" "load")])
7696 (define_insn "*tldo_lduw1_sp64"
7697 [(set (match_operand:DI 0 "register_operand" "=r")
7698 (zero_extend:DI (mem:SI (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 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7704 [(set_attr "type" "load")])
7706 (define_insn "*tldo_ldsw1_sp64"
7707 [(set (match_operand:DI 0 "register_operand" "=r")
7708 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7709 (match_operand 3 "tld_symbolic_operand" "")]
7711 (match_operand:DI 1 "register_operand" "r")))))]
7712 "TARGET_TLS && TARGET_ARCH64"
7713 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7714 [(set_attr "type" "sload")
7715 (set_attr "us3load_type" "3cycle")])
7717 (define_insn "*tldo_ldx_sp64"
7718 [(set (match_operand:DI 0 "register_operand" "=r")
7719 (mem:DI (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 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7725 [(set_attr "type" "load")])
7727 (define_insn "*tldo_stb_sp32"
7728 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7729 (match_operand 3 "tld_symbolic_operand" "")]
7731 (match_operand:SI 1 "register_operand" "r")))
7732 (match_operand:QI 0 "register_operand" "r"))]
7733 "TARGET_TLS && TARGET_ARCH32"
7734 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7735 [(set_attr "type" "store")])
7737 (define_insn "*tldo_stb_sp64"
7738 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7739 (match_operand 3 "tld_symbolic_operand" "")]
7741 (match_operand:DI 1 "register_operand" "r")))
7742 (match_operand:QI 0 "register_operand" "r"))]
7743 "TARGET_TLS && TARGET_ARCH64"
7744 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7745 [(set_attr "type" "store")])
7747 (define_insn "*tldo_sth_sp32"
7748 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7749 (match_operand 3 "tld_symbolic_operand" "")]
7751 (match_operand:SI 1 "register_operand" "r")))
7752 (match_operand:HI 0 "register_operand" "r"))]
7753 "TARGET_TLS && TARGET_ARCH32"
7754 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7755 [(set_attr "type" "store")])
7757 (define_insn "*tldo_sth_sp64"
7758 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7759 (match_operand 3 "tld_symbolic_operand" "")]
7761 (match_operand:DI 1 "register_operand" "r")))
7762 (match_operand:HI 0 "register_operand" "r"))]
7763 "TARGET_TLS && TARGET_ARCH64"
7764 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7765 [(set_attr "type" "store")])
7767 (define_insn "*tldo_stw_sp32"
7768 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7769 (match_operand 3 "tld_symbolic_operand" "")]
7771 (match_operand:SI 1 "register_operand" "r")))
7772 (match_operand:SI 0 "register_operand" "r"))]
7773 "TARGET_TLS && TARGET_ARCH32"
7774 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7775 [(set_attr "type" "store")])
7777 (define_insn "*tldo_stw_sp64"
7778 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7779 (match_operand 3 "tld_symbolic_operand" "")]
7781 (match_operand:DI 1 "register_operand" "r")))
7782 (match_operand:SI 0 "register_operand" "r"))]
7783 "TARGET_TLS && TARGET_ARCH64"
7784 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7785 [(set_attr "type" "store")])
7787 (define_insn "*tldo_stx_sp64"
7788 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7789 (match_operand 3 "tld_symbolic_operand" "")]
7791 (match_operand:DI 1 "register_operand" "r")))
7792 (match_operand:DI 0 "register_operand" "r"))]
7793 "TARGET_TLS && TARGET_ARCH64"
7794 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7795 [(set_attr "type" "store")])
7798 ;; Stack protector instructions.
7800 (define_expand "stack_protect_set"
7801 [(match_operand 0 "memory_operand" "")
7802 (match_operand 1 "memory_operand" "")]
7805 #ifdef TARGET_THREAD_SSP_OFFSET
7806 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7807 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7808 operands[1] = gen_rtx_MEM (Pmode, addr);
7811 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7813 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7817 (define_insn "stack_protect_setsi"
7818 [(set (match_operand:SI 0 "memory_operand" "=m")
7819 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7820 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7822 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7823 [(set_attr "type" "multi")
7824 (set_attr "length" "3")])
7826 (define_insn "stack_protect_setdi"
7827 [(set (match_operand:DI 0 "memory_operand" "=m")
7828 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7829 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7831 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7832 [(set_attr "type" "multi")
7833 (set_attr "length" "3")])
7835 (define_expand "stack_protect_test"
7836 [(match_operand 0 "memory_operand" "")
7837 (match_operand 1 "memory_operand" "")
7838 (match_operand 2 "" "")]
7842 #ifdef TARGET_THREAD_SSP_OFFSET
7843 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7844 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7845 operands[1] = gen_rtx_MEM (Pmode, addr);
7849 result = gen_reg_rtx (Pmode);
7850 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7851 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7852 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7856 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7857 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7858 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7859 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7864 (define_insn "stack_protect_testsi"
7865 [(set (reg:CC CC_REG)
7866 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7867 (match_operand:SI 1 "memory_operand" "m")]
7869 (set (match_scratch:SI 3 "=r") (const_int 0))
7870 (clobber (match_scratch:SI 2 "=&r"))]
7872 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7873 [(set_attr "type" "multi")
7874 (set_attr "length" "4")])
7876 (define_insn "stack_protect_testdi"
7877 [(set (match_operand:DI 0 "register_operand" "=&r")
7878 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7879 (match_operand:DI 2 "memory_operand" "m")]
7881 (set (match_scratch:DI 3 "=r") (const_int 0))]
7883 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7884 [(set_attr "type" "multi")
7885 (set_attr "length" "4")])
7887 ;; Vector instructions.
7889 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7890 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7891 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7893 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
7894 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7895 (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7896 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7897 (V1DI "double") (V2SI "double") (V4HI "double")
7900 (define_expand "mov<VMALL:mode>"
7901 [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7902 (match_operand:VMALL 1 "general_operand" ""))]
7905 if (sparc_expand_move (<VMALL:MODE>mode, operands))
7909 (define_insn "*mov<VM32:mode>_insn"
7910 [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
7911 (match_operand:VM32 1 "input_operand" "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
7913 && (register_operand (operands[0], <VM32:MODE>mode)
7914 || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7927 [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv")
7928 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
7930 (define_insn "*mov<VM64:mode>_insn_sp64"
7931 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
7932 (match_operand:VM64 1 "input_operand" "Y,C,e,m,e,Y, m,*r, e,*r,*r"))]
7935 && (register_operand (operands[0], <VM64:MODE>mode)
7936 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7949 [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*")
7950 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
7952 (define_insn "*mov<VM64:mode>_insn_sp32"
7953 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
7954 (match_operand:VM64 1 "input_operand" "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
7957 && (register_operand (operands[0], <VM64:MODE>mode)
7958 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7972 [(set_attr "type" "visl,visl,vismv,*,*,fpload,fpstore,store,load,store,*,*")
7973 (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
7974 (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
7977 [(set (match_operand:VM64 0 "memory_operand" "")
7978 (match_operand:VM64 1 "register_operand" ""))]
7982 && (((REGNO (operands[1]) % 2) != 0)
7983 || ! mem_min_alignment (operands[0], 8))
7984 && offsettable_memref_p (operands[0])"
7985 [(clobber (const_int 0))]
7989 word0 = adjust_address (operands[0], SImode, 0);
7990 word1 = adjust_address (operands[0], SImode, 4);
7992 emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
7993 emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
7998 [(set (match_operand:VM64 0 "register_operand" "")
7999 (match_operand:VM64 1 "register_operand" ""))]
8003 && sparc_split_regreg_legitimate (operands[0], operands[1])"
8004 [(clobber (const_int 0))]
8006 rtx set_dest = operands[0];
8007 rtx set_src = operands[1];
8011 dest1 = gen_highpart (SImode, set_dest);
8012 dest2 = gen_lowpart (SImode, set_dest);
8013 src1 = gen_highpart (SImode, set_src);
8014 src2 = gen_lowpart (SImode, set_src);
8016 /* Now emit using the real source and destination we found, swapping
8017 the order if we detect overlap. */
8018 if (reg_overlap_mentioned_p (dest1, src2))
8020 emit_insn (gen_movsi (dest2, src2));
8021 emit_insn (gen_movsi (dest1, src1));
8025 emit_insn (gen_movsi (dest1, src1));
8026 emit_insn (gen_movsi (dest2, src2));
8031 (define_expand "vec_init<mode>"
8032 [(match_operand:VMALL 0 "register_operand" "")
8033 (match_operand:VMALL 1 "" "")]
8036 sparc_expand_vector_init (operands[0], operands[1]);
8040 (define_code_iterator plusminus [plus minus])
8041 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
8043 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
8045 (define_insn "<plusminus_insn><mode>3"
8046 [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
8047 (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
8048 (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
8050 "fp<plusminus_insn><vbits>\t%1, %2, %0"
8051 [(set_attr "type" "fga")
8052 (set_attr "fptype" "<vfptype>")])
8054 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8055 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
8056 (V1DI "") (V2SI "") (V4HI "") (V8QI "")])
8057 (define_code_iterator vlop [ior and xor])
8058 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
8059 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
8061 (define_insn "<code><mode>3"
8062 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8063 (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8064 (match_operand:VL 2 "register_operand" "<vconstr>")))]
8066 "f<vlinsn><vlsuf>\t%1, %2, %0"
8067 [(set_attr "type" "visl")
8068 (set_attr "fptype" "<vfptype>")])
8070 (define_insn "*not_<code><mode>3"
8071 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8072 (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8073 (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8075 "f<vlninsn><vlsuf>\t%1, %2, %0"
8076 [(set_attr "type" "visl")
8077 (set_attr "fptype" "<vfptype>")])
8079 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8080 (define_insn "*nand<mode>_vis"
8081 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8082 (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8083 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8085 "fnand<vlsuf>\t%1, %2, %0"
8086 [(set_attr "type" "visl")
8087 (set_attr "fptype" "<vfptype>")])
8089 (define_code_iterator vlnotop [ior and])
8091 (define_insn "*<code>_not1<mode>_vis"
8092 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8093 (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8094 (match_operand:VL 2 "register_operand" "<vconstr>")))]
8096 "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
8097 [(set_attr "type" "visl")
8098 (set_attr "fptype" "<vfptype>")])
8100 (define_insn "*<code>_not2<mode>_vis"
8101 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8102 (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8103 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8105 "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
8106 [(set_attr "type" "visl")
8107 (set_attr "fptype" "<vfptype>")])
8109 (define_insn "one_cmpl<mode>2"
8110 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8111 (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
8113 "fnot1<vlsuf>\t%1, %0"
8114 [(set_attr "type" "visl")
8115 (set_attr "fptype" "<vfptype>")])
8117 ;; Hard to generate VIS instructions. We have builtins for these.
8119 (define_insn "fpack16_vis"
8120 [(set (match_operand:V4QI 0 "register_operand" "=f")
8121 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
8126 [(set_attr "type" "fgm_pack")
8127 (set_attr "fptype" "double")])
8129 (define_insn "fpackfix_vis"
8130 [(set (match_operand:V2HI 0 "register_operand" "=f")
8131 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
8136 [(set_attr "type" "fgm_pack")
8137 (set_attr "fptype" "double")])
8139 (define_insn "fpack32_vis"
8140 [(set (match_operand:V8QI 0 "register_operand" "=e")
8141 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8142 (match_operand:V8QI 2 "register_operand" "e")
8146 "fpack32\t%1, %2, %0"
8147 [(set_attr "type" "fgm_pack")
8148 (set_attr "fptype" "double")])
8150 (define_insn "fexpand_vis"
8151 [(set (match_operand:V4HI 0 "register_operand" "=e")
8152 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8156 [(set_attr "type" "fga")
8157 (set_attr "fptype" "double")])
8159 (define_insn "fpmerge_vis"
8160 [(set (match_operand:V8QI 0 "register_operand" "=e")
8162 (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8163 (match_operand:V4QI 2 "register_operand" "f"))
8164 (parallel [(const_int 0) (const_int 4)
8165 (const_int 1) (const_int 5)
8166 (const_int 2) (const_int 6)
8167 (const_int 3) (const_int 7)])))]
8169 "fpmerge\t%1, %2, %0"
8170 [(set_attr "type" "fga")
8171 (set_attr "fptype" "double")])
8173 (define_insn "vec_interleave_lowv8qi"
8174 [(set (match_operand:V8QI 0 "register_operand" "=e")
8176 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8177 (match_operand:V8QI 2 "register_operand" "f"))
8178 (parallel [(const_int 0) (const_int 8)
8179 (const_int 1) (const_int 9)
8180 (const_int 2) (const_int 10)
8181 (const_int 3) (const_int 11)])))]
8183 "fpmerge\t%L1, %L2, %0"
8184 [(set_attr "type" "fga")
8185 (set_attr "fptype" "double")])
8187 (define_insn "vec_interleave_highv8qi"
8188 [(set (match_operand:V8QI 0 "register_operand" "=e")
8190 (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8191 (match_operand:V8QI 2 "register_operand" "f"))
8192 (parallel [(const_int 4) (const_int 12)
8193 (const_int 5) (const_int 13)
8194 (const_int 6) (const_int 14)
8195 (const_int 7) (const_int 15)])))]
8197 "fpmerge\t%H1, %H2, %0"
8198 [(set_attr "type" "fga")
8199 (set_attr "fptype" "double")])
8201 ;; Partitioned multiply instructions
8202 (define_insn "fmul8x16_vis"
8203 [(set (match_operand:V4HI 0 "register_operand" "=e")
8204 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8205 (match_operand:V4HI 2 "register_operand" "e")]
8208 "fmul8x16\t%1, %2, %0"
8209 [(set_attr "type" "fgm_mul")
8210 (set_attr "fptype" "double")])
8212 (define_insn "fmul8x16au_vis"
8213 [(set (match_operand:V4HI 0 "register_operand" "=e")
8214 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8215 (match_operand:V2HI 2 "register_operand" "f")]
8218 "fmul8x16au\t%1, %2, %0"
8219 [(set_attr "type" "fgm_mul")
8220 (set_attr "fptype" "double")])
8222 (define_insn "fmul8x16al_vis"
8223 [(set (match_operand:V4HI 0 "register_operand" "=e")
8224 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8225 (match_operand:V2HI 2 "register_operand" "f")]
8228 "fmul8x16al\t%1, %2, %0"
8229 [(set_attr "type" "fgm_mul")
8230 (set_attr "fptype" "double")])
8232 (define_insn "fmul8sux16_vis"
8233 [(set (match_operand:V4HI 0 "register_operand" "=e")
8234 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8235 (match_operand:V4HI 2 "register_operand" "e")]
8238 "fmul8sux16\t%1, %2, %0"
8239 [(set_attr "type" "fgm_mul")
8240 (set_attr "fptype" "double")])
8242 (define_insn "fmul8ulx16_vis"
8243 [(set (match_operand:V4HI 0 "register_operand" "=e")
8244 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8245 (match_operand:V4HI 2 "register_operand" "e")]
8248 "fmul8ulx16\t%1, %2, %0"
8249 [(set_attr "type" "fgm_mul")
8250 (set_attr "fptype" "double")])
8252 (define_insn "fmuld8sux16_vis"
8253 [(set (match_operand:V2SI 0 "register_operand" "=e")
8254 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8255 (match_operand:V2HI 2 "register_operand" "f")]
8258 "fmuld8sux16\t%1, %2, %0"
8259 [(set_attr "type" "fgm_mul")
8260 (set_attr "fptype" "double")])
8262 (define_insn "fmuld8ulx16_vis"
8263 [(set (match_operand:V2SI 0 "register_operand" "=e")
8264 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8265 (match_operand:V2HI 2 "register_operand" "f")]
8268 "fmuld8ulx16\t%1, %2, %0"
8269 [(set_attr "type" "fgm_mul")
8270 (set_attr "fptype" "double")])
8272 (define_expand "wrgsr_vis"
8273 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8276 if (! TARGET_ARCH64)
8278 emit_insn (gen_wrgsr_v8plus (operands[0]));
8283 (define_insn "*wrgsr_sp64"
8284 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8285 "TARGET_VIS && TARGET_ARCH64"
8286 "wr\t%%g0, %0, %%gsr"
8287 [(set_attr "type" "gsr")])
8289 (define_insn "wrgsr_v8plus"
8290 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8291 (clobber (match_scratch:SI 1 "=X,&h"))]
8292 "TARGET_VIS && ! TARGET_ARCH64"
8294 if (GET_CODE (operands[0]) == CONST_INT
8295 || sparc_check_64 (operands[0], insn))
8296 return "wr\t%%g0, %0, %%gsr";
8298 output_asm_insn("srl\t%L0, 0, %L0", operands);
8299 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8301 [(set_attr "type" "multi")])
8303 (define_expand "rdgsr_vis"
8304 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8307 if (! TARGET_ARCH64)
8309 emit_insn (gen_rdgsr_v8plus (operands[0]));
8314 (define_insn "*rdgsr_sp64"
8315 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8316 "TARGET_VIS && TARGET_ARCH64"
8318 [(set_attr "type" "gsr")])
8320 (define_insn "rdgsr_v8plus"
8321 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8322 (clobber (match_scratch:SI 1 "=&h"))]
8323 "TARGET_VIS && ! TARGET_ARCH64"
8325 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8327 [(set_attr "type" "multi")])
8329 ;; Using faligndata only makes sense after an alignaddr since the choice of
8330 ;; bytes to take out of each operand is dependent on the results of the last
8332 (define_insn "faligndata<VM64:mode>_vis"
8333 [(set (match_operand:VM64 0 "register_operand" "=e")
8334 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8335 (match_operand:VM64 2 "register_operand" "e")
8339 "faligndata\t%1, %2, %0"
8340 [(set_attr "type" "fga")
8341 (set_attr "fptype" "double")])
8343 (define_insn "alignaddrsi_vis"
8344 [(set (match_operand:SI 0 "register_operand" "=r")
8345 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8346 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8347 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8348 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8350 "alignaddr\t%r1, %r2, %0"
8351 [(set_attr "type" "gsr")])
8353 (define_insn "alignaddrdi_vis"
8354 [(set (match_operand:DI 0 "register_operand" "=r")
8355 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8356 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8357 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8358 (plus:DI (match_dup 1) (match_dup 2)))]
8360 "alignaddr\t%r1, %r2, %0"
8361 [(set_attr "type" "gsr")])
8363 (define_insn "alignaddrlsi_vis"
8364 [(set (match_operand:SI 0 "register_operand" "=r")
8365 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8366 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8367 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8368 (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8371 "alignaddrl\t%r1, %r2, %0"
8372 [(set_attr "type" "gsr")])
8374 (define_insn "alignaddrldi_vis"
8375 [(set (match_operand:DI 0 "register_operand" "=r")
8376 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8377 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8378 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8379 (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8382 "alignaddrl\t%r1, %r2, %0"
8383 [(set_attr "type" "gsr")])
8385 (define_insn "pdist_vis"
8386 [(set (match_operand:DI 0 "register_operand" "=e")
8387 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8388 (match_operand:V8QI 2 "register_operand" "e")
8389 (match_operand:DI 3 "register_operand" "0")]
8393 [(set_attr "type" "pdist")
8394 (set_attr "fptype" "double")])
8396 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8397 ;; with the same operands.
8398 (define_insn "edge8<P:mode>_vis"
8399 [(set (reg:CC_NOOV CC_REG)
8400 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8401 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8403 (set (match_operand:P 0 "register_operand" "=r")
8404 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8406 "edge8\t%r1, %r2, %0"
8407 [(set_attr "type" "edge")])
8409 (define_insn "edge8l<P:mode>_vis"
8410 [(set (reg:CC_NOOV CC_REG)
8411 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8412 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8414 (set (match_operand:P 0 "register_operand" "=r")
8415 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8417 "edge8l\t%r1, %r2, %0"
8418 [(set_attr "type" "edge")])
8420 (define_insn "edge16<P:mode>_vis"
8421 [(set (reg:CC_NOOV CC_REG)
8422 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8423 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8425 (set (match_operand:P 0 "register_operand" "=r")
8426 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8428 "edge16\t%r1, %r2, %0"
8429 [(set_attr "type" "edge")])
8431 (define_insn "edge16l<P:mode>_vis"
8432 [(set (reg:CC_NOOV CC_REG)
8433 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8434 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8436 (set (match_operand:P 0 "register_operand" "=r")
8437 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8439 "edge16l\t%r1, %r2, %0"
8440 [(set_attr "type" "edge")])
8442 (define_insn "edge32<P:mode>_vis"
8443 [(set (reg:CC_NOOV CC_REG)
8444 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8445 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8447 (set (match_operand:P 0 "register_operand" "=r")
8448 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8450 "edge32\t%r1, %r2, %0"
8451 [(set_attr "type" "edge")])
8453 (define_insn "edge32l<P:mode>_vis"
8454 [(set (reg:CC_NOOV CC_REG)
8455 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8456 (match_operand:P 2 "register_or_zero_operand" "rJ"))
8458 (set (match_operand:P 0 "register_operand" "=r")
8459 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8461 "edge32l\t%r1, %r2, %0"
8462 [(set_attr "type" "edge")])
8464 (define_code_iterator gcond [le ne gt eq])
8465 (define_mode_iterator GCM [V4HI V2SI])
8466 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8468 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8469 [(set (match_operand:P 0 "register_operand" "=r")
8470 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8471 (match_operand:GCM 2 "register_operand" "e"))]
8474 "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8475 [(set_attr "type" "visl")
8476 (set_attr "fptype" "double")])
8478 (define_expand "vcond<mode><mode>"
8479 [(match_operand:GCM 0 "register_operand" "")
8480 (match_operand:GCM 1 "register_operand" "")
8481 (match_operand:GCM 2 "register_operand" "")
8482 (match_operator 3 ""
8483 [(match_operand:GCM 4 "register_operand" "")
8484 (match_operand:GCM 5 "register_operand" "")])]
8487 sparc_expand_vcond (<MODE>mode, operands,
8488 UNSPEC_CMASK<gcm_name>,
8493 (define_expand "vconduv8qiv8qi"
8494 [(match_operand:V8QI 0 "register_operand" "")
8495 (match_operand:V8QI 1 "register_operand" "")
8496 (match_operand:V8QI 2 "register_operand" "")
8497 (match_operator 3 ""
8498 [(match_operand:V8QI 4 "register_operand" "")
8499 (match_operand:V8QI 5 "register_operand" "")])]
8502 sparc_expand_vcond (V8QImode, operands,
8508 (define_insn "array8<P:mode>_vis"
8509 [(set (match_operand:P 0 "register_operand" "=r")
8510 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8511 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8514 "array8\t%r1, %r2, %0"
8515 [(set_attr "type" "array")])
8517 (define_insn "array16<P:mode>_vis"
8518 [(set (match_operand:P 0 "register_operand" "=r")
8519 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8520 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8523 "array16\t%r1, %r2, %0"
8524 [(set_attr "type" "array")])
8526 (define_insn "array32<P:mode>_vis"
8527 [(set (match_operand:P 0 "register_operand" "=r")
8528 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8529 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8532 "array32\t%r1, %r2, %0"
8533 [(set_attr "type" "array")])
8535 (define_insn "bmaskdi_vis"
8536 [(set (match_operand:DI 0 "register_operand" "=r")
8537 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8538 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8539 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8540 (plus:DI (match_dup 1) (match_dup 2)))]
8542 "bmask\t%r1, %r2, %0"
8543 [(set_attr "type" "array")])
8545 (define_insn "bmasksi_vis"
8546 [(set (match_operand:SI 0 "register_operand" "=r")
8547 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8548 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8549 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8550 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8552 "bmask\t%r1, %r2, %0"
8553 [(set_attr "type" "array")])
8555 (define_insn "bshuffle<VM64:mode>_vis"
8556 [(set (match_operand:VM64 0 "register_operand" "=e")
8557 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8558 (match_operand:VM64 2 "register_operand" "e")
8562 "bshuffle\t%1, %2, %0"
8563 [(set_attr "type" "fga")
8564 (set_attr "fptype" "double")])
8566 ;; The rtl expanders will happily convert constant permutations on other
8567 ;; modes down to V8QI. Rely on this to avoid the complexity of the byte
8568 ;; order of the permutation.
8569 (define_expand "vec_perm_constv8qi"
8570 [(match_operand:V8QI 0 "register_operand" "")
8571 (match_operand:V8QI 1 "register_operand" "")
8572 (match_operand:V8QI 2 "register_operand" "")
8573 (match_operand:V8QI 3 "" "")]
8576 unsigned int i, mask;
8577 rtx sel = operands[3];
8579 for (i = mask = 0; i < 8; ++i)
8580 mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8581 sel = force_reg (SImode, gen_int_mode (mask, SImode));
8583 emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx));
8584 emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8588 ;; Unlike constant permutation, we can vastly simplify the compression of
8589 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8590 ;; width of the input is.
8591 (define_expand "vec_perm<mode>"
8592 [(match_operand:VM64 0 "register_operand" "")
8593 (match_operand:VM64 1 "register_operand" "")
8594 (match_operand:VM64 2 "register_operand" "")
8595 (match_operand:VM64 3 "register_operand" "")]
8598 sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8599 emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8603 ;; VIS 2.0 adds edge variants which do not set the condition codes
8604 (define_insn "edge8n<P:mode>_vis"
8605 [(set (match_operand:P 0 "register_operand" "=r")
8606 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8607 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8610 "edge8n\t%r1, %r2, %0"
8611 [(set_attr "type" "edgen")])
8613 (define_insn "edge8ln<P:mode>_vis"
8614 [(set (match_operand:P 0 "register_operand" "=r")
8615 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8616 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8619 "edge8ln\t%r1, %r2, %0"
8620 [(set_attr "type" "edgen")])
8622 (define_insn "edge16n<P:mode>_vis"
8623 [(set (match_operand:P 0 "register_operand" "=r")
8624 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8625 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8628 "edge16n\t%r1, %r2, %0"
8629 [(set_attr "type" "edgen")])
8631 (define_insn "edge16ln<P:mode>_vis"
8632 [(set (match_operand:P 0 "register_operand" "=r")
8633 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8634 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8637 "edge16ln\t%r1, %r2, %0"
8638 [(set_attr "type" "edgen")])
8640 (define_insn "edge32n<P:mode>_vis"
8641 [(set (match_operand:P 0 "register_operand" "=r")
8642 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8643 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8646 "edge32n\t%r1, %r2, %0"
8647 [(set_attr "type" "edgen")])
8649 (define_insn "edge32ln<P:mode>_vis"
8650 [(set (match_operand:P 0 "register_operand" "=r")
8651 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8652 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8655 "edge32ln\t%r1, %r2, %0"
8656 [(set_attr "type" "edge")])
8658 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8659 (define_insn "cmask8<P:mode>_vis"
8660 [(set (reg:DI GSR_REG)
8661 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8666 [(set_attr "type" "fga")])
8668 (define_insn "cmask16<P:mode>_vis"
8669 [(set (reg:DI GSR_REG)
8670 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8675 [(set_attr "type" "fga")])
8677 (define_insn "cmask32<P:mode>_vis"
8678 [(set (reg:DI GSR_REG)
8679 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8684 [(set_attr "type" "fga")])
8686 (define_insn "fchksm16_vis"
8687 [(set (match_operand:V4HI 0 "register_operand" "=e")
8688 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8689 (match_operand:V4HI 2 "register_operand" "e")]
8692 "fchksm16\t%1, %2, %0"
8693 [(set_attr "type" "fga")])
8695 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8696 (define_code_attr vis3_shift_insn
8697 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8698 (define_code_attr vis3_shift_patname
8699 [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8701 (define_insn "v<vis3_shift_patname><mode>3"
8702 [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8703 (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8704 (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8706 "<vis3_shift_insn><vbits>\t%1, %2, %0"
8707 [(set_attr "type" "fga")])
8709 (define_insn "pdistn<mode>_vis"
8710 [(set (match_operand:P 0 "register_operand" "=r")
8711 (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8712 (match_operand:V8QI 2 "register_operand" "e")]
8715 "pdistn\t%1, %2, %0"
8716 [(set_attr "type" "pdistn")
8717 (set_attr "fptype" "double")])
8719 (define_insn "fmean16_vis"
8720 [(set (match_operand:V4HI 0 "register_operand" "=e")
8726 (match_operand:V4HI 1 "register_operand" "e"))
8728 (match_operand:V4HI 2 "register_operand" "e")))
8729 (const_vector:V4SI [(const_int 1) (const_int 1)
8730 (const_int 1) (const_int 1)]))
8733 "fmean16\t%1, %2, %0"
8734 [(set_attr "type" "fga")])
8736 (define_insn "fp<plusminus_insn>64_vis"
8737 [(set (match_operand:V1DI 0 "register_operand" "=e")
8738 (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8739 (match_operand:V1DI 2 "register_operand" "e")))]
8741 "fp<plusminus_insn>64\t%1, %2, %0"
8742 [(set_attr "type" "fga")])
8744 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8745 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8746 (define_code_attr vis3_addsub_ss_insn
8747 [(ss_plus "fpadds") (ss_minus "fpsubs")])
8748 (define_code_attr vis3_addsub_ss_patname
8749 [(ss_plus "ssadd") (ss_minus "sssub")])
8751 (define_insn "<vis3_addsub_ss_patname><mode>3"
8752 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8753 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8754 (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8756 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
8757 [(set_attr "type" "fga")])
8759 (define_insn "fucmp<code>8<P:mode>_vis"
8760 [(set (match_operand:P 0 "register_operand" "=r")
8761 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8762 (match_operand:V8QI 2 "register_operand" "e"))]
8765 "fucmp<code>8\t%1, %2, %0"
8766 [(set_attr "type" "visl")])
8768 (define_insn "*naddsf3"
8769 [(set (match_operand:SF 0 "register_operand" "=f")
8770 (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8771 (match_operand:SF 2 "register_operand" "f"))))]
8773 "fnadds\t%1, %2, %0"
8774 [(set_attr "type" "fp")])
8776 (define_insn "*nadddf3"
8777 [(set (match_operand:DF 0 "register_operand" "=e")
8778 (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8779 (match_operand:DF 2 "register_operand" "e"))))]
8781 "fnaddd\t%1, %2, %0"
8782 [(set_attr "type" "fp")
8783 (set_attr "fptype" "double")])
8785 (define_insn "*nmulsf3"
8786 [(set (match_operand:SF 0 "register_operand" "=f")
8787 (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8788 (match_operand:SF 2 "register_operand" "f")))]
8790 "fnmuls\t%1, %2, %0"
8791 [(set_attr "type" "fpmul")])
8793 (define_insn "*nmuldf3"
8794 [(set (match_operand:DF 0 "register_operand" "=e")
8795 (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8796 (match_operand:DF 2 "register_operand" "e")))]
8798 "fnmuld\t%1, %2, %0"
8799 [(set_attr "type" "fpmul")
8800 (set_attr "fptype" "double")])
8802 (define_insn "*nmuldf3_extend"
8803 [(set (match_operand:DF 0 "register_operand" "=e")
8804 (mult:DF (neg:DF (float_extend:DF
8805 (match_operand:SF 1 "register_operand" "f")))
8807 (match_operand:SF 2 "register_operand" "f"))))]
8809 "fnsmuld\t%1, %2, %0"
8810 [(set_attr "type" "fpmul")
8811 (set_attr "fptype" "double")])
8813 (define_insn "fhaddsf_vis"
8814 [(set (match_operand:SF 0 "register_operand" "=f")
8815 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8816 (match_operand:SF 2 "register_operand" "f")]
8819 "fhadds\t%1, %2, %0"
8820 [(set_attr "type" "fp")])
8822 (define_insn "fhadddf_vis"
8823 [(set (match_operand:DF 0 "register_operand" "=f")
8824 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8825 (match_operand:DF 2 "register_operand" "f")]
8828 "fhaddd\t%1, %2, %0"
8829 [(set_attr "type" "fp")
8830 (set_attr "fptype" "double")])
8832 (define_insn "fhsubsf_vis"
8833 [(set (match_operand:SF 0 "register_operand" "=f")
8834 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8835 (match_operand:SF 2 "register_operand" "f")]
8838 "fhsubs\t%1, %2, %0"
8839 [(set_attr "type" "fp")])
8841 (define_insn "fhsubdf_vis"
8842 [(set (match_operand:DF 0 "register_operand" "=f")
8843 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8844 (match_operand:DF 2 "register_operand" "f")]
8847 "fhsubd\t%1, %2, %0"
8848 [(set_attr "type" "fp")
8849 (set_attr "fptype" "double")])
8851 (define_insn "fnhaddsf_vis"
8852 [(set (match_operand:SF 0 "register_operand" "=f")
8853 (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8854 (match_operand:SF 2 "register_operand" "f")]
8857 "fnhadds\t%1, %2, %0"
8858 [(set_attr "type" "fp")])
8860 (define_insn "fnhadddf_vis"
8861 [(set (match_operand:DF 0 "register_operand" "=f")
8862 (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8863 (match_operand:DF 2 "register_operand" "f")]
8866 "fnhaddd\t%1, %2, %0"
8867 [(set_attr "type" "fp")
8868 (set_attr "fptype" "double")])
8870 (define_expand "umulxhi_vis"
8871 [(set (match_operand:DI 0 "register_operand" "")
8874 (mult:TI (zero_extend:TI
8875 (match_operand:DI 1 "arith_operand" ""))
8877 (match_operand:DI 2 "arith_operand" "")))
8881 if (! TARGET_ARCH64)
8883 emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8888 (define_insn "*umulxhi_sp64"
8889 [(set (match_operand:DI 0 "register_operand" "=r")
8892 (mult:TI (zero_extend:TI
8893 (match_operand:DI 1 "arith_operand" "%r"))
8895 (match_operand:DI 2 "arith_operand" "rI")))
8897 "TARGET_VIS3 && TARGET_ARCH64"
8898 "umulxhi\t%1, %2, %0"
8899 [(set_attr "type" "imul")])
8901 (define_insn "umulxhi_v8plus"
8902 [(set (match_operand:DI 0 "register_operand" "=r,h")
8905 (mult:TI (zero_extend:TI
8906 (match_operand:DI 1 "arith_operand" "%r,0"))
8908 (match_operand:DI 2 "arith_operand" "rI,rI")))
8910 (clobber (match_scratch:SI 3 "=&h,X"))
8911 (clobber (match_scratch:SI 4 "=&h,X"))]
8912 "TARGET_VIS3 && ! TARGET_ARCH64"
8913 "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8914 [(set_attr "type" "imul")
8915 (set_attr "length" "9,8")])
8917 (define_expand "xmulx_vis"
8918 [(set (match_operand:DI 0 "register_operand" "")
8920 (unspec:TI [(zero_extend:TI
8921 (match_operand:DI 1 "arith_operand" ""))
8923 (match_operand:DI 2 "arith_operand" ""))]
8927 if (! TARGET_ARCH64)
8929 emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8934 (define_insn "*xmulx_sp64"
8935 [(set (match_operand:DI 0 "register_operand" "=r")
8937 (unspec:TI [(zero_extend:TI
8938 (match_operand:DI 1 "arith_operand" "%r"))
8940 (match_operand:DI 2 "arith_operand" "rI"))]
8942 "TARGET_VIS3 && TARGET_ARCH64"
8944 [(set_attr "type" "imul")])
8946 (define_insn "xmulx_v8plus"
8947 [(set (match_operand:DI 0 "register_operand" "=r,h")
8949 (unspec:TI [(zero_extend:TI
8950 (match_operand:DI 1 "arith_operand" "%r,0"))
8952 (match_operand:DI 2 "arith_operand" "rI,rI"))]
8954 (clobber (match_scratch:SI 3 "=&h,X"))
8955 (clobber (match_scratch:SI 4 "=&h,X"))]
8956 "TARGET_VIS3 && ! TARGET_ARCH64"
8957 "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8958 [(set_attr "type" "imul")
8959 (set_attr "length" "9,8")])
8961 (define_expand "xmulxhi_vis"
8962 [(set (match_operand:DI 0 "register_operand" "")
8965 (unspec:TI [(zero_extend:TI
8966 (match_operand:DI 1 "arith_operand" ""))
8968 (match_operand:DI 2 "arith_operand" ""))]
8973 if (! TARGET_ARCH64)
8975 emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
8980 (define_insn "*xmulxhi_sp64"
8981 [(set (match_operand:DI 0 "register_operand" "=r")
8984 (unspec:TI [(zero_extend:TI
8985 (match_operand:DI 1 "arith_operand" "%r"))
8987 (match_operand:DI 2 "arith_operand" "rI"))]
8990 "TARGET_VIS3 && TARGET_ARCH64"
8991 "xmulxhi\t%1, %2, %0"
8992 [(set_attr "type" "imul")])
8994 (define_insn "xmulxhi_v8plus"
8995 [(set (match_operand:DI 0 "register_operand" "=r,h")
8998 (unspec:TI [(zero_extend:TI
8999 (match_operand:DI 1 "arith_operand" "%r,0"))
9001 (match_operand:DI 2 "arith_operand" "rI,rI"))]
9004 (clobber (match_scratch:SI 3 "=&h,X"))
9005 (clobber (match_scratch:SI 4 "=&h,X"))]
9006 "TARGET_VIS3 && !TARGET_ARCH64"
9007 "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
9008 [(set_attr "type" "imul")
9009 (set_attr "length" "9,8")])