aboutsummaryrefslogtreecommitdiffstats
path: root/src/3rdparty/masm/disassembler
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2014-05-16 14:46:58 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-06-02 16:13:21 +0200
commit5f52fee4733d54109c7483abbea1610dff747846 (patch)
tree696a41454e45ebf3ca86961e6367c2aca09f9fb6 /src/3rdparty/masm/disassembler
parentbc9e86ef5813f6c2b28a2e10324cf0a2401e53df (diff)
V4: teach the disassembler about VMUL, VCVT, and VCMP on ARM.
Change-Id: I2fee1d9d8c9b6437e6237388f2b0d93243fe601d Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/3rdparty/masm/disassembler')
-rw-r--r--src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp72
-rw-r--r--src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h58
2 files changed, 130 insertions, 0 deletions
diff --git a/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp b/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp
index ae7b0859ed..d9afdd447a 100644
--- a/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp
+++ b/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp
@@ -120,6 +120,9 @@ static Opcode32GroupInitializer opcode32BitGroupList[] = {
OPCODE_GROUP_ENTRY(0x7, ARMv7DOpcodeFPTransfer),
OPCODE_GROUP_ENTRY(0x7, ARMv7DOpcodeVMSR),
OPCODE_GROUP_ENTRY(0x7, ARMv7DOpcodeVADDVSUB),
+ OPCODE_GROUP_ENTRY(0x7, ARMv7DOpcodeVMUL),
+ OPCODE_GROUP_ENTRY(0x7, ARMv7DOpcodeVCVT),
+ OPCODE_GROUP_ENTRY(0x7, ARMv7DOpcodeVCMP),
OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeDataProcessingModifiedImmediate),
OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeConditionalBranchT3),
OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeBranchOrBranchLink),
@@ -1579,6 +1582,75 @@ const char* ARMv7DOpcodeVADDVSUB::format()
return m_formatBuffer;
}
+const char* ARMv7DOpcodeVMUL::format()
+{
+ char regPrefix = sz() ? 'd' : 's';
+ appendInstructionName("vmul");
+ appendFPRegisterName(regPrefix, vd());
+ appendSeparator();
+ appendFPRegisterName(regPrefix, vn());
+ appendSeparator();
+ appendFPRegisterName(regPrefix, vm());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeVCVT::format()
+{
+ char dregPrefix;
+ char mregPrefix;
+ const char *n1, *n2;
+
+ switch (opc2()) {
+ case 5:
+ n1 = op() ? "vcvtr.s32." : "vcvt.s32.";
+ n2 = sz() ? "f64" : "f32";
+ dregPrefix = 's';
+ mregPrefix = sz() ? 'd' : 's';
+ break;
+ case 4:
+ n1 = op() ? "vcvtr.u32." : "vcvt.u32.";
+ n2 = sz() ? "f64" : "f32";
+ dregPrefix = 's';
+ mregPrefix = sz() ? 'd' : 's';
+ break;
+ case 0:
+ n1 = sz() ? "vcvt.f64." : "vcvt.f32.";
+ n2 = op() ? "s32" : "u32";
+ dregPrefix = sz() ? 'd' : 's';
+ mregPrefix = 's';
+ break;
+ default:
+ n1 = "vcvt.?";
+ n2 = ".?";
+ break;
+ }
+
+ char buf[42];
+ snprintf(buf, 42, "%s%s", n1, n2);
+ appendInstructionName(buf);
+
+ appendFPRegisterName(dregPrefix, vd());
+ appendSeparator();
+ appendFPRegisterName(mregPrefix, vm());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeVCMP::format()
+{
+ char regPrefix = sz() ? 'd' : 's';
+ appendInstructionName(e() ? "vcmpe" : "vcmp");
+ appendFPRegisterName(regPrefix, vd());
+ appendSeparator();
+ if (zero())
+ appendString("#0.0");
+ else
+ appendFPRegisterName(regPrefix, vm());
+
+ return m_formatBuffer;
+}
+
const char* ARMv7DOpcodeVLDRVSTR::format()
{
appendInstructionName(opName());
diff --git a/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h b/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h
index 5bcb6b15b9..051d05525a 100644
--- a/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h
+++ b/src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h
@@ -1146,6 +1146,8 @@ public:
protected:
const char* format();
+ // FIXME: the register encoding for single precision is not correct.
+
unsigned sz() { return (m_opcode >> 8) & 0x1; }
unsigned isSub() { return (m_opcode >> 6) & 0x1; }
unsigned vm() { return (m_opcode & 0xf) | ((m_opcode >> 1) & 0x10); }
@@ -1153,6 +1155,62 @@ protected:
unsigned vd() { return ((m_opcode >> 12) & 0xf) | ((m_opcode >> 18) & 0x10); }
};
+class ARMv7DOpcodeVMUL : public ARMv7D32BitOpcode {
+public:
+ static const uint32_t s_mask = 0xffb00e50;
+ static const uint32_t s_pattern = 0xee200a00;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVMUL, thisObj);
+
+protected:
+ const char* format();
+
+ // FIXME: the register encoding for single precision is not correct.
+
+ unsigned sz() { return (m_opcode >> 8) & 0x1; }
+ unsigned vm() { return (m_opcode & 0xf) | ((m_opcode >> 1) & 0x10); }
+ unsigned vn() { return ((m_opcode >> 16) & 0xf) | ((m_opcode >> 3) & 0x10); }
+ unsigned vd() { return ((m_opcode >> 12) & 0xf) | ((m_opcode >> 18) & 0x10); }
+};
+
+class ARMv7DOpcodeVCVT : public ARMv7D32BitOpcode {
+public:
+ static const uint32_t s_mask = 0xffb80a50;
+ static const uint32_t s_pattern = 0xeeb80a40;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVCVT, thisObj);
+
+protected:
+ const char* format();
+
+ // FIXME: the register encoding for single precision is not correct.
+
+ unsigned sz() { return (m_opcode >> 8) & 0x1; }
+ unsigned op() { return (m_opcode >> 7) & 0x1; }
+ unsigned opc2() { return (m_opcode >> 16) & 0x7; }
+ unsigned vm() { return (m_opcode & 0xf) | ((m_opcode >> 1) & 0x10); }
+ unsigned vd() { return ((m_opcode >> 12) & 0xf) | ((m_opcode >> 18) & 0x10); }
+};
+
+class ARMv7DOpcodeVCMP : public ARMv7D32BitOpcode {
+public:
+ static const uint32_t s_mask = 0xffbf0e50;
+ static const uint32_t s_pattern = 0xeeb40a40;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVCMP, thisObj);
+
+protected:
+ const char* format();
+
+ // FIXME: the register encoding for single precision is not correct.
+
+ unsigned sz() { return (m_opcode >> 8) & 0x1; }
+ unsigned e() { return (m_opcode >> 7) & 0x1; }
+ unsigned zero() { return (m_opcode >> 16) & 0x1; }
+ unsigned vm() { return (m_opcode & 0xf) | ((m_opcode >> 1) & 0x10); }
+ unsigned vd() { return ((m_opcode >> 12) & 0xf) | ((m_opcode >> 18) & 0x10); }
+};
+
class ARMv7DOpcodeVLDRVSTR : public ARMv7D32BitOpcode {
public:
static const uint32_t s_mask = 0xff200a00;