Bug 1272014 - Masm code for 64-bit bit counting. r=bbouvier

--HG--
extra : rebase_source : 37d8142f0b3bf2c418b15ebf60b1d15dc34c1511
This commit is contained in:
Lars T Hansen 2016-05-11 17:01:08 +02:00
parent 2f12a83ecd
commit cb72513c65
2 changed files with 34 additions and 0 deletions

View File

@ -813,6 +813,9 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void clz32(Register src, Register dest, bool knownNotZero) DEFINED_ON(x86_shared);
inline void ctz32(Register src, Register dest, bool knownNotZero) DEFINED_ON(x86_shared);
inline void clz64(Register64 src, Register64 dest, bool knownNotZero) DEFINED_ON(x64);
inline void ctz64(Register64 src, Register64 dest, bool knownNotZero) DEFINED_ON(x64);
// temp may be invalid only if the chip has the POPCNT instruction.
inline void popcnt32(Register src, Register dest, Register temp) DEFINED_ON(x86_shared);

View File

@ -273,6 +273,37 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest)
shrq(imm, dest.reg);
}
// ===============================================================
// Bit counting functions
void
MacroAssembler::clz64(Register64 src, Register64 dest, bool knownNotZero)
{
// On very recent chips (Haswell and newer) there is actually an
// LZCNT instruction that does all of this.
bsrq(src.reg, dest.reg);
if (!knownNotZero) {
Label nonzero;
j(Assembler::NonZero, &nonzero);
movq(ImmWord(0x7F), dest.reg);
bind(&nonzero);
}
xorq(Imm32(0x3F), dest.reg);
}
void
MacroAssembler::ctz64(Register64 src, Register64 dest, bool knownNotZero)
{
bsfq(src.reg, dest.reg);
if (!knownNotZero) {
Label nonzero;
j(Assembler::NonZero, &nonzero);
movq(ImmWord(64), dest.reg);
bind(&nonzero);
}
}
// ===============================================================
// Branch functions