From 59c2b779289127ead0f699bcba147becfad89f40 Mon Sep 17 00:00:00 2001 From: Shi Dan Date: Mon, 10 Oct 2016 17:08:32 +0800 Subject: [PATCH] Bug 1290812 - Part 34: Implement the 64bit variant of Clz and Ctz on mips32. r=bbouvier --- js/src/jit/MacroAssembler.h | 4 ++-- js/src/jit/mips32/CodeGenerator-mips32.cpp | 18 +++++++++++++++ js/src/jit/mips32/CodeGenerator-mips32.h | 2 ++ js/src/jit/mips32/MacroAssembler-mips32-inl.h | 33 +++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 2 deletions(-) --- js/src/jit/MacroAssembler.h | 4 +-- js/src/jit/mips32/CodeGenerator-mips32.cpp | 18 ++++++++++ js/src/jit/mips32/CodeGenerator-mips32.h | 2 ++ js/src/jit/mips32/MacroAssembler-mips32-inl.h | 33 +++++++++++++++++++ 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index fff89c6dcca6..3c1902b8395f 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -920,8 +920,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void clz32(Register src, Register dest, bool knownNotZero) PER_SHARED_ARCH; inline void ctz32(Register src, Register dest, bool knownNotZero) PER_SHARED_ARCH; - inline void clz64(Register64 src, Register dest) DEFINED_ON(x86, x64, arm, mips64); - inline void ctz64(Register64 src, Register dest) DEFINED_ON(x86, x64, arm, mips64); + inline void clz64(Register64 src, Register dest) DEFINED_ON(x86, x64, arm, mips32, mips64); + inline void ctz64(Register64 src, Register dest) DEFINED_ON(x86, x64, arm, mips32, mips64); // On x86_shared, temp may be Invalid only if the chip has the POPCNT instruction. // On ARM, temp may never be Invalid. diff --git a/js/src/jit/mips32/CodeGenerator-mips32.cpp b/js/src/jit/mips32/CodeGenerator-mips32.cpp index f2b7e1cfbd88..e64b7656a420 100644 --- a/js/src/jit/mips32/CodeGenerator-mips32.cpp +++ b/js/src/jit/mips32/CodeGenerator-mips32.cpp @@ -479,6 +479,24 @@ CodeGeneratorMIPS::visitWrapInt64ToInt32(LWrapInt64ToInt32* lir) masm.move32(ToRegister(input.high()), output); } +void +CodeGeneratorMIPS::visitClzI64(LClzI64* lir) +{ + Register64 input = ToRegister64(lir->getInt64Operand(0)); + Register64 output = ToOutRegister64(lir); + masm.clz64(input, output.low); + masm.move32(Imm32(0), output.high); +} + +void +CodeGeneratorMIPS::visitCtzI64(LCtzI64* lir) +{ + Register64 input = ToRegister64(lir->getInt64Operand(0)); + Register64 output = ToOutRegister64(lir); + masm.ctz64(input, output.low); + masm.move32(Imm32(0), output.high); +} + void CodeGeneratorMIPS::setReturnDoubleRegs(LiveRegisterSet* regs) { diff --git a/js/src/jit/mips32/CodeGenerator-mips32.h b/js/src/jit/mips32/CodeGenerator-mips32.h index 7170df4235da..5f63865a354d 100644 --- a/js/src/jit/mips32/CodeGenerator-mips32.h +++ b/js/src/jit/mips32/CodeGenerator-mips32.h @@ -44,6 +44,8 @@ class CodeGeneratorMIPS : public CodeGeneratorMIPSShared void visitUDivOrModI64(LUDivOrModI64* lir); void visitExtendInt32ToInt64(LExtendInt32ToInt64* lir); void visitWrapInt64ToInt32(LWrapInt64ToInt32* lir); + void visitClzI64(LClzI64* ins); + void visitCtzI64(LCtzI64* ins); // Out of line visitors. void visitOutOfLineBailout(OutOfLineBailout* ool); diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index 4d1633502da6..b9063afa1be9 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -666,6 +666,39 @@ MacroAssembler::rotateRight64(Register shift, Register64 src, Register64 dest, R // =============================================================== // Bit counting functions +void +MacroAssembler::clz64(Register64 src, Register dest) +{ + Label done, low; + + ma_b(src.high, Imm32(0), &low, Equal); + as_clz(dest, src.high); + ma_b(&done); + + bind(&low); + as_clz(dest, src.low); + ma_addu(dest, Imm32(32)); + + bind(&done); +} + +void +MacroAssembler::ctz64(Register64 src, Register dest) +{ + Label done, high; + + ma_b(src.low, Imm32(0), &high, Equal); + + ma_ctz(dest, src.low); + ma_b(&done); + + bind(&high); + ma_ctz(dest, src.high); + ma_addu(dest, Imm32(32)); + + bind(&done); +} + void MacroAssembler::popcnt64(Register64 src, Register64 dest, Register tmp) {