diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-05-16 14:46:58 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-06-02 16:13:21 +0200 |
commit | 5f52fee4733d54109c7483abbea1610dff747846 (patch) | |
tree | 696a41454e45ebf3ca86961e6367c2aca09f9fb6 /src/3rdparty | |
parent | bc9e86ef5813f6c2b28a2e10324cf0a2401e53df (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')
-rw-r--r-- | src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp | 72 | ||||
-rw-r--r-- | src/3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h | 58 |
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; |