aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp4
-rw-r--r--src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h6
-rw-r--r--src/qml/jit/qv4binop.cpp36
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);