Mercurial > hg > truffle
comparison src/cpu/x86/vm/x86_64.ad @ 775:93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
Summary: These methods can be instrinsified by using bit scan, bit test, and population count instructions.
Reviewed-by: kvn, never
author | twisti |
---|---|
date | Wed, 06 May 2009 00:27:52 -0700 |
parents | fbde8ec322d0 |
children | 2056494941db |
comparison
equal
deleted
inserted
replaced
755:36ee9b69616e | 775:93c14e5562c4 |
---|---|
1978 internal_word_Relocation::spec(float_address), | 1978 internal_word_Relocation::spec(float_address), |
1979 RELOC_DISP32); | 1979 RELOC_DISP32); |
1980 } | 1980 } |
1981 | 1981 |
1982 | 1982 |
1983 const bool Matcher::match_rule_supported(int opcode) { | |
1984 if (!has_match_rule(opcode)) | |
1985 return false; | |
1986 | |
1987 return true; // Per default match rules are supported. | |
1988 } | |
1989 | |
1983 int Matcher::regnum_to_fpu_offset(int regnum) | 1990 int Matcher::regnum_to_fpu_offset(int regnum) |
1984 { | 1991 { |
1985 return regnum - 32; // The FP registers are in the second chunk | 1992 return regnum - 32; // The FP registers are in the second chunk |
1986 } | 1993 } |
1987 | 1994 |
7651 | 7658 |
7652 format %{ "movq_bswap $dst, $src" %} | 7659 format %{ "movq_bswap $dst, $src" %} |
7653 opcode(0x0F, 0xC8, 0x89); /* Opcode 0F C8 89 */ | 7660 opcode(0x0F, 0xC8, 0x89); /* Opcode 0F C8 89 */ |
7654 ins_encode( REX_reg_wide(src), OpcP, opc2_reg(src), REX_reg_mem_wide(src, dst), OpcT, reg_mem(src, dst) ); | 7661 ins_encode( REX_reg_wide(src), OpcP, opc2_reg(src), REX_reg_mem_wide(src, dst), OpcT, reg_mem(src, dst) ); |
7655 ins_pipe( ialu_mem_reg ); | 7662 ins_pipe( ialu_mem_reg ); |
7663 %} | |
7664 | |
7665 | |
7666 //---------- Zeros Count Instructions ------------------------------------------ | |
7667 | |
7668 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ | |
7669 predicate(UseCountLeadingZerosInstruction); | |
7670 match(Set dst (CountLeadingZerosI src)); | |
7671 effect(KILL cr); | |
7672 | |
7673 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} | |
7674 ins_encode %{ | |
7675 __ lzcntl($dst$$Register, $src$$Register); | |
7676 %} | |
7677 ins_pipe(ialu_reg); | |
7678 %} | |
7679 | |
7680 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ | |
7681 predicate(!UseCountLeadingZerosInstruction); | |
7682 match(Set dst (CountLeadingZerosI src)); | |
7683 effect(KILL cr); | |
7684 | |
7685 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" | |
7686 "jnz skip\n\t" | |
7687 "movl $dst, -1\n" | |
7688 "skip:\n\t" | |
7689 "negl $dst\n\t" | |
7690 "addl $dst, 31" %} | |
7691 ins_encode %{ | |
7692 Register Rdst = $dst$$Register; | |
7693 Register Rsrc = $src$$Register; | |
7694 Label skip; | |
7695 __ bsrl(Rdst, Rsrc); | |
7696 __ jccb(Assembler::notZero, skip); | |
7697 __ movl(Rdst, -1); | |
7698 __ bind(skip); | |
7699 __ negl(Rdst); | |
7700 __ addl(Rdst, BitsPerInt - 1); | |
7701 %} | |
7702 ins_pipe(ialu_reg); | |
7703 %} | |
7704 | |
7705 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ | |
7706 predicate(UseCountLeadingZerosInstruction); | |
7707 match(Set dst (CountLeadingZerosL src)); | |
7708 effect(KILL cr); | |
7709 | |
7710 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} | |
7711 ins_encode %{ | |
7712 __ lzcntq($dst$$Register, $src$$Register); | |
7713 %} | |
7714 ins_pipe(ialu_reg); | |
7715 %} | |
7716 | |
7717 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ | |
7718 predicate(!UseCountLeadingZerosInstruction); | |
7719 match(Set dst (CountLeadingZerosL src)); | |
7720 effect(KILL cr); | |
7721 | |
7722 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" | |
7723 "jnz skip\n\t" | |
7724 "movl $dst, -1\n" | |
7725 "skip:\n\t" | |
7726 "negl $dst\n\t" | |
7727 "addl $dst, 63" %} | |
7728 ins_encode %{ | |
7729 Register Rdst = $dst$$Register; | |
7730 Register Rsrc = $src$$Register; | |
7731 Label skip; | |
7732 __ bsrq(Rdst, Rsrc); | |
7733 __ jccb(Assembler::notZero, skip); | |
7734 __ movl(Rdst, -1); | |
7735 __ bind(skip); | |
7736 __ negl(Rdst); | |
7737 __ addl(Rdst, BitsPerLong - 1); | |
7738 %} | |
7739 ins_pipe(ialu_reg); | |
7740 %} | |
7741 | |
7742 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ | |
7743 match(Set dst (CountTrailingZerosI src)); | |
7744 effect(KILL cr); | |
7745 | |
7746 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" | |
7747 "jnz done\n\t" | |
7748 "movl $dst, 32\n" | |
7749 "done:" %} | |
7750 ins_encode %{ | |
7751 Register Rdst = $dst$$Register; | |
7752 Label done; | |
7753 __ bsfl(Rdst, $src$$Register); | |
7754 __ jccb(Assembler::notZero, done); | |
7755 __ movl(Rdst, BitsPerInt); | |
7756 __ bind(done); | |
7757 %} | |
7758 ins_pipe(ialu_reg); | |
7759 %} | |
7760 | |
7761 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ | |
7762 match(Set dst (CountTrailingZerosL src)); | |
7763 effect(KILL cr); | |
7764 | |
7765 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" | |
7766 "jnz done\n\t" | |
7767 "movl $dst, 64\n" | |
7768 "done:" %} | |
7769 ins_encode %{ | |
7770 Register Rdst = $dst$$Register; | |
7771 Label done; | |
7772 __ bsfq(Rdst, $src$$Register); | |
7773 __ jccb(Assembler::notZero, done); | |
7774 __ movl(Rdst, BitsPerLong); | |
7775 __ bind(done); | |
7776 %} | |
7777 ins_pipe(ialu_reg); | |
7656 %} | 7778 %} |
7657 | 7779 |
7658 | 7780 |
7659 //---------- Population Count Instructions ------------------------------------- | 7781 //---------- Population Count Instructions ------------------------------------- |
7660 | 7782 |