From 4fe80d7e0ab4fc1a8478c3735aafc6c1f2db7ed6 Mon Sep 17 00:00:00 2001 From: Shi Dan Date: Mon, 10 Oct 2016 17:08:18 +0800 Subject: [PATCH] Bug 1290812 - Part 23: Implement the 64bit variant of Shift on mips32. r=bbouvier --- js/src/jit/MacroAssembler.h | 11 ++- js/src/jit/mips32/MacroAssembler-mips32-inl.h | 134 ++++++++++++++++++++++++-- 2 files changed, 133 insertions(+), 12 deletions(-) --- js/src/jit/MacroAssembler.h | 11 +- js/src/jit/mips32/MacroAssembler-mips32-inl.h | 134 ++++++++++++++++-- 2 files changed, 133 insertions(+), 12 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index eea55e1a7b01..335cd9ca5a12 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -875,17 +875,20 @@ class MacroAssembler : public MacroAssemblerSpecific inline void lshift64(Imm32 imm, Register64 dest) PER_ARCH; inline void rshift64(Imm32 imm, Register64 dest) PER_ARCH; - inline void rshift64Arithmetic(Imm32 imm, Register64 dest) DEFINED_ON(x86, x64, arm, mips64); + inline void rshift64Arithmetic(Imm32 imm, Register64 dest) + DEFINED_ON(x86, x64, arm, mips32, mips64); // On x86_shared these have the constraint that shift must be in CL. inline void lshift32(Register shift, Register srcDest) PER_SHARED_ARCH; inline void rshift32(Register shift, Register srcDest) PER_SHARED_ARCH; inline void rshift32Arithmetic(Register shift, Register srcDest) PER_SHARED_ARCH; - inline void lshift64(Register shift, Register64 srcDest) DEFINED_ON(x86, x64, arm, mips64); - inline void rshift64(Register shift, Register64 srcDest) DEFINED_ON(x86, x64, arm, mips64); + inline void lshift64(Register shift, Register64 srcDest) + DEFINED_ON(x86, x64, arm, mips32, mips64); + inline void rshift64(Register shift, Register64 srcDest) + DEFINED_ON(x86, x64, arm, mips32, mips64); inline void rshift64Arithmetic(Register shift, Register64 srcDest) - DEFINED_ON(x86, x64, arm, mips64); + DEFINED_ON(x86, x64, arm, mips32, mips64); // =============================================================== // Rotation functions diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index db0609a6e1d0..a8a86f470843 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -239,10 +239,46 @@ MacroAssembler::lshift64(Imm32 imm, Register64 dest) { MOZ_ASSERT(0 <= imm.value && imm.value < 64); ScratchRegisterScope scratch(*this); - as_sll(dest.high, dest.high, imm.value); - as_srl(scratch, dest.low, 32 - imm.value); - as_or(dest.high, dest.high, scratch); - as_sll(dest.low, dest.low, imm.value); + + if (imm.value == 0) { + return; + } else if (imm.value < 32) { + as_sll(dest.high, dest.high, imm.value); + as_srl(scratch, dest.low, 32 - imm.value); + as_or(dest.high, dest.high, scratch); + as_sll(dest.low, dest.low, imm.value); + } else { + as_sll(dest.high, dest.low, imm.value - 32); + move32(Imm32(0), dest.low); + } +} + +void +MacroAssembler::lshift64(Register unmaskedShift, Register64 dest) +{ + Label done, less; + ScratchRegisterScope shift(*this); + + ma_and(shift, unmaskedShift, Imm32(0x3f)); + ma_b(shift, Imm32(0), &done, Equal); + + ma_sll(dest.high, dest.high, shift); + ma_subu(shift, shift, Imm32(32)); + ma_b(shift, Imm32(0), &less, LessThan); + + ma_sll(dest.high, dest.low, shift); + move32(Imm32(0), dest.low); + ma_b(&done); + + bind(&less); + ma_li(SecondScratchReg, Imm32(0)); + as_subu(shift, SecondScratchReg, shift); + ma_srl(SecondScratchReg, dest.low, shift); + as_or(dest.high, dest.high, SecondScratchReg); + ma_and(shift, unmaskedShift, Imm32(0x3f)); + ma_sll(dest.low, dest.low, shift); + + bind(&done); } void @@ -264,10 +300,92 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) { MOZ_ASSERT(0 <= imm.value && imm.value < 64); ScratchRegisterScope scratch(*this); - as_srl(dest.low, dest.low, imm.value); - as_sll(scratch, dest.high, 32 - imm.value); - as_or(dest.low, dest.low, scratch); - as_srl(dest.high, dest.high, imm.value); + + if (imm.value < 32) { + as_srl(dest.low, dest.low, imm.value); + as_sll(scratch, dest.high, 32 - imm.value); + as_or(dest.low, dest.low, scratch); + as_srl(dest.high, dest.high, imm.value); + } else if (imm.value == 32) { + ma_move(dest.low, dest.high); + move32(Imm32(0), dest.high); + } else { + ma_srl(dest.low, dest.high, Imm32(imm.value - 32)); + move32(Imm32(0), dest.high); + } +} + +void +MacroAssembler::rshift64(Register unmaskedShift, Register64 dest) +{ + Label done, less; + ScratchRegisterScope shift(*this); + + ma_and(shift, unmaskedShift, Imm32(0x3f)); + ma_srl(dest.low, dest.low, shift); + ma_subu(shift, shift, Imm32(32)); + ma_b(shift, Imm32(0), &less, LessThan); + + ma_srl(dest.low, dest.high, shift); + move32(Imm32(0), dest.high); + ma_b(&done); + + bind(&less); + ma_li(SecondScratchReg, Imm32(0)); + as_subu(shift, SecondScratchReg, shift); + ma_sll(SecondScratchReg, dest.high, shift); + as_or(dest.low, dest.low, SecondScratchReg); + ma_and(shift, unmaskedShift, Imm32(0x3f)); + ma_srl(dest.high, dest.high, shift); + + bind(&done); +} + +void +MacroAssembler::rshift64Arithmetic(Imm32 imm, Register64 dest) +{ + MOZ_ASSERT(0 <= imm.value && imm.value < 64); + ScratchRegisterScope scratch(*this); + + if (imm.value < 32) { + as_srl(dest.low, dest.low, imm.value); + as_sll(scratch, dest.high, 32 - imm.value); + as_or(dest.low, dest.low, scratch); + as_sra(dest.high, dest.high, imm.value); + } else if (imm.value == 32) { + ma_move(dest.low, dest.high); + as_sra(dest.high, dest.high, 31); + } else { + as_sra(dest.low, dest.high, imm.value - 32); + as_sra(dest.high, dest.high, 31); + } +} + +void +MacroAssembler::rshift64Arithmetic(Register unmaskedShift, Register64 dest) +{ + Label done, less; + + ScratchRegisterScope shift(*this); + ma_and(shift, unmaskedShift, Imm32(0x3f)); + + ma_srl(dest.low, dest.low, shift); + ma_subu(shift, shift, Imm32(32)); + ma_b(shift, Imm32(0), &less, LessThan); + + ma_sra(dest.low, dest.high, shift); + as_sra(dest.high, dest.high, 31); + ma_b(&done); + + bind(&less); + ma_li(SecondScratchReg, Imm32(0)); + as_subu(shift, SecondScratchReg, shift); + ma_sll(SecondScratchReg, dest.high, shift); + as_or(dest.low, dest.low, SecondScratchReg); + ma_and(shift, unmaskedShift, Imm32(0x3f)); + ma_sra(dest.high, dest.high, shift); + + bind(&done); } // ===============================================================