diff options
-rw-r--r-- | src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp | 4 | ||||
-rw-r--r-- | src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h | 6 | ||||
-rw-r--r-- | src/qml/jit/qv4binop.cpp | 36 |
3 files changed, 35 insertions, 11 deletions
diff --git a/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp b/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp index 81063e2b11..ae7b0859ed 100644 --- a/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp +++ b/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp @@ -49,7 +49,7 @@ const char* const ARMv7DOpcode::s_optionName[8] = { }; const char* const ARMv7DOpcode::s_shiftNames[4] = { - "lsl", "lsr", "asl", "ror" + "lsl", "lsr", "asr", "ror" }; const char* const ARMv7DOpcode::s_specialRegisterNames[3] = { "sp", "lr", "pc" }; @@ -944,7 +944,7 @@ const char* ARMv7DOpcodeDataProcessingShiftedReg::format() appendSeparator(); appendRegisterName(rm()); appendSeparator(); - appendUnsignedImmediate(immediate5()); + appendImmShift(type(), immediate5()); return m_formatBuffer; } diff --git a/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h b/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h index ca5f955ba1..5bcb6b15b9 100644 --- a/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h +++ b/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h @@ -69,6 +69,7 @@ protected: static const char* conditionName(unsigned condition) { return s_conditionNames[condition & 0xf]; } static const char* shiftName(unsigned shiftValue) { return s_shiftNames[shiftValue & 0x3]; } + static bool isRightShift(unsigned shiftValue) { return shiftValue == 1 || shiftValue == 2; } bool inITBlock() { return m_ITConditionIndex < m_ITBlocksize; } bool startingITBlock() { return m_ITConditionIndex == m_ITBlocksize + 1; } @@ -514,7 +515,10 @@ protected: const char* opName() { return shiftName(op()); } unsigned op() { return (m_opcode >> 12) & 0x3; } - unsigned immediate5() { return (m_opcode >> 6) & 0x1f; } + unsigned immediate5() { + unsigned imm = (m_opcode >> 6) & 0x1f; + return isRightShift(op()) && imm == 0 ? 32 : imm; + } }; class ARMv7DOpcodeMiscAddSubSP : public ARMv7D16BitOpcode { diff --git a/src/qml/jit/qv4binop.cpp b/src/qml/jit/qv4binop.cpp index 74024752cf..344bbf56e0 100644 --- a/src/qml/jit/qv4binop.cpp +++ b/src/qml/jit/qv4binop.cpp @@ -299,13 +299,19 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Temp *ta Q_ASSERT(rightSource->type == IR::SInt32Type); if (IR::Const *c = rightSource->asConst()) { - as->lshift32(as->toInt32Register(leftSource, Assembler::ReturnValueRegister), - Assembler::TrustedImm32(int(c->value) & 0x1f), targetReg); + if (int(c->value) == 0) + as->move(as->toInt32Register(leftSource, Assembler::ReturnValueRegister), targetReg); + else + as->lshift32(as->toInt32Register(leftSource, Assembler::ReturnValueRegister), + Assembler::TrustedImm32(int(c->value) & 0x1f), targetReg); } else { as->move(as->toInt32Register(rightSource, Assembler::ScratchRegister), Assembler::ScratchRegister); - if (!rightSource->asConst()) - as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister); +#if CPU(ARM) || CPU(X86) || CPU(X86_64) + // The ARM assembler will generate this for us, and Intel will do it on the CPU. +#else + as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister); +#endif as->lshift32(as->toInt32Register(leftSource, targetReg), Assembler::ScratchRegister, targetReg); } as->storeInt32(targetReg, target); @@ -314,12 +320,19 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Temp *ta Q_ASSERT(rightSource->type == IR::SInt32Type); if (IR::Const *c = rightSource->asConst()) { - as->rshift32(as->toInt32Register(leftSource, Assembler::ReturnValueRegister), - Assembler::TrustedImm32(int(c->value) & 0x1f), targetReg); + if (int(c->value) == 0) + as->move(as->toInt32Register(leftSource, Assembler::ReturnValueRegister), targetReg); + else + as->rshift32(as->toInt32Register(leftSource, Assembler::ReturnValueRegister), + Assembler::TrustedImm32(int(c->value) & 0x1f), targetReg); } else { as->move(as->toInt32Register(rightSource, Assembler::ScratchRegister), Assembler::ScratchRegister); +#if CPU(ARM) || CPU(X86) || CPU(X86_64) + // The ARM assembler will generate this for us, and Intel will do it on the CPU. +#else as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister); +#endif as->rshift32(as->toInt32Register(leftSource, targetReg), Assembler::ScratchRegister, targetReg); } as->storeInt32(targetReg, target); @@ -328,12 +341,19 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Temp *ta Q_ASSERT(rightSource->type == IR::SInt32Type); if (IR::Const *c = rightSource->asConst()) { - as->urshift32(as->toInt32Register(leftSource, Assembler::ReturnValueRegister), - Assembler::TrustedImm32(int(c->value) & 0x1f), targetReg); + if (int(c->value) == 0) + as->move(as->toInt32Register(leftSource, Assembler::ReturnValueRegister), targetReg); + else + as->urshift32(as->toInt32Register(leftSource, Assembler::ReturnValueRegister), + Assembler::TrustedImm32(int(c->value) & 0x1f), targetReg); } else { as->move(as->toInt32Register(rightSource, Assembler::ScratchRegister), Assembler::ScratchRegister); +#if CPU(ARM) || CPU(X86) || CPU(X86_64) + // The ARM assembler will generate this for us, and Intel will do it on the CPU. +#else as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister); +#endif as->urshift32(as->toInt32Register(leftSource, targetReg), Assembler::ScratchRegister, targetReg); } as->storeUInt32(targetReg, target); |