Bug 1290812 - Part 13: Implement the 64bit variant of PopCnt on mips64. r=lth

---
 js/src/jit/MacroAssembler.h                        |  3 ++-
 .../jit/mips-shared/CodeGenerator-mips-shared.cpp  | 10 ++++++++
 js/src/jit/mips-shared/CodeGenerator-mips-shared.h |  1 +
 js/src/jit/mips64/MacroAssembler-mips64-inl.h      | 29 ++++++++++++++++++++++
 js/src/jit/mips64/MacroAssembler-mips64.cpp        |  6 +++++
 js/src/jit/mips64/MacroAssembler-mips64.h          |  1 +
 6 files changed, 49 insertions(+), 1 deletion(-)
This commit is contained in:
Heiher 2016-10-10 17:08:05 +08:00
parent 60ccb943fc
commit 55e61372ea
6 changed files with 49 additions and 1 deletions

View File

@ -926,7 +926,8 @@ class MacroAssembler : public MacroAssemblerSpecific
DEFINED_ON(arm, x86_shared, mips_shared);
// temp may be invalid only if the chip has the POPCNT instruction.
inline void popcnt64(Register64 src, Register64 dest, Register temp) DEFINED_ON(x86, x64, arm);
inline void popcnt64(Register64 src, Register64 dest, Register temp)
DEFINED_ON(x86, x64, arm, mips64);
// ===============================================================
// Branch functions

View File

@ -1073,6 +1073,16 @@ CodeGeneratorMIPSShared::visitPopcntI(LPopcntI* ins)
masm.popcnt32(input, output, tmp);
}
void
CodeGeneratorMIPSShared::visitPopcntI64(LPopcntI64* ins)
{
Register64 input = ToRegister64(ins->getInt64Operand(0));
Register64 output = ToOutRegister64(ins);
Register tmp = ToRegister(ins->getTemp(0));
masm.popcnt64(input, output, tmp);
}
void
CodeGeneratorMIPSShared::visitPowHalfD(LPowHalfD* ins)
{

View File

@ -152,6 +152,7 @@ class CodeGeneratorMIPSShared : public CodeGeneratorShared
virtual void visitClzI(LClzI* ins);
virtual void visitCtzI(LCtzI* ins);
virtual void visitPopcntI(LPopcntI* ins);
virtual void visitPopcntI64(LPopcntI64* lir);
virtual void visitTestIAndBranch(LTestIAndBranch* test);
virtual void visitCompare(LCompare* comp);

View File

@ -400,6 +400,35 @@ MacroAssembler::rotateRight64(Register count, Register64 src, Register64 dest, R
ma_dror(dest.reg, src.reg, count);
}
// ===============================================================
// Bit counting functions
void
MacroAssembler::popcnt64(Register64 input, Register64 output, Register tmp)
{
ma_move(output.reg, input.reg);
ma_dsra(tmp, input.reg, Imm32(1));
ma_li(ScratchRegister, ImmWord(0x5555555555555555UL));
ma_and(tmp, ScratchRegister);
ma_dsubu(output.reg, tmp);
ma_dsra(tmp, output.reg, Imm32(2));
ma_li(ScratchRegister, ImmWord(0x3333333333333333UL));
ma_and(output.reg, ScratchRegister);
ma_and(tmp, ScratchRegister);
ma_daddu(output.reg, tmp);
ma_dsrl(tmp, output.reg, Imm32(4));
ma_daddu(output.reg, tmp);
ma_li(ScratchRegister, ImmWord(0xF0F0F0F0F0F0F0FUL));
ma_and(output.reg, ScratchRegister);
ma_dsll(tmp, output.reg, Imm32(8));
ma_daddu(output.reg, tmp);
ma_dsll(tmp, output.reg, Imm32(16));
ma_daddu(output.reg, tmp);
ma_dsll(tmp, output.reg, Imm32(32));
ma_daddu(output.reg, tmp);
ma_dsra(output.reg, output.reg, Imm32(56));
}
// ===============================================================
// Branch functions

View File

@ -458,6 +458,12 @@ MacroAssemblerMIPS64::ma_dsubu(Register rd, Register rs, Imm32 imm)
}
}
void
MacroAssemblerMIPS64::ma_dsubu(Register rd, Register rs)
{
as_dsubu(rd, rd, rs);
}
void
MacroAssemblerMIPS64::ma_dsubu(Register rd, Imm32 imm)
{

View File

@ -99,6 +99,7 @@ class MacroAssemblerMIPS64 : public MacroAssemblerMIPSShared
// subtract
void ma_dsubu(Register rd, Register rs, Imm32 imm);
void ma_dsubu(Register rd, Register rs);
void ma_dsubu(Register rd, Imm32 imm);
void ma_subTestOverflow(Register rd, Register rs, Register rt, Label* overflow);