forked from OSchip/llvm-project
Add Encoding T2 & T3 of the PUSH instructions to the g_arm_opcodes table.
Plus add an extra field ARMInstrSize to the table entry type 'ARMOpcode'. llvm-svn: 124140
This commit is contained in:
parent
78c9f78fc9
commit
d8c2a48298
|
@ -18,6 +18,18 @@ namespace lldb_private {
|
||||||
// not permitted for many Thumb register specifiers.
|
// not permitted for many Thumb register specifiers.
|
||||||
static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; }
|
static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; }
|
||||||
|
|
||||||
|
// Returns an integer result equal to the number of bits of x that are ones.
|
||||||
|
static inline uint32_t BitCount(uint32_t x)
|
||||||
|
{
|
||||||
|
// c accumulates the total bits set in x
|
||||||
|
uint32_t c;
|
||||||
|
for (c = 0; x; ++c)
|
||||||
|
{
|
||||||
|
x &= x - 1; // clear the least significant bit set
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace lldb_private
|
} // namespace lldb_private
|
||||||
|
|
||||||
#endif // lldb_ARMUtils_h_
|
#endif // lldb_ARMUtils_h_
|
||||||
|
|
|
@ -67,7 +67,7 @@ using namespace lldb_private;
|
||||||
#define ARMv8 (1u << 8)
|
#define ARMv8 (1u << 8)
|
||||||
#define ARMvAll (0xffffffffu)
|
#define ARMvAll (0xffffffffu)
|
||||||
|
|
||||||
typedef enum ARMEncoding
|
typedef enum
|
||||||
{
|
{
|
||||||
eEncodingA1,
|
eEncodingA1,
|
||||||
eEncodingA2,
|
eEncodingA2,
|
||||||
|
@ -81,19 +81,26 @@ typedef enum ARMEncoding
|
||||||
eEncodingT5,
|
eEncodingT5,
|
||||||
} ARMEncoding;
|
} ARMEncoding;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
eSize16,
|
||||||
|
eSize32
|
||||||
|
} ARMInstrSize;
|
||||||
|
|
||||||
// Typedef for the callback function used during the emulation.
|
// Typedef for the callback function used during the emulation.
|
||||||
// Pass along (ARMEncoding)encoding as the callback data.
|
// Pass along (ARMEncoding)encoding as the callback data.
|
||||||
typedef bool (*EmulateCallback) (EmulateInstructionARM *emulator, ARMEncoding encoding);
|
typedef bool (*EmulateCallback) (EmulateInstructionARM *emulator, ARMEncoding encoding);
|
||||||
|
|
||||||
typedef struct ARMOpcode
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
uint32_t variants;
|
uint32_t variants;
|
||||||
ARMEncoding encoding;
|
ARMEncoding encoding;
|
||||||
|
ARMInstrSize size;
|
||||||
EmulateCallback callback;
|
EmulateCallback callback;
|
||||||
const char *name;
|
const char *name;
|
||||||
};
|
} ARMOpcode;
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
EmulateARMPushEncoding (EmulateInstructionARM *emulator, ARMEncoding encoding)
|
EmulateARMPushEncoding (EmulateInstructionARM *emulator, ARMEncoding encoding)
|
||||||
|
@ -137,16 +144,31 @@ EmulateARMPushEncoding (EmulateInstructionARM *emulator, ARMEncoding encoding)
|
||||||
if (!success)
|
if (!success)
|
||||||
return false;
|
return false;
|
||||||
uint32_t registers = 0;
|
uint32_t registers = 0;
|
||||||
|
uint32_t t; // UInt(Rt)
|
||||||
switch (encoding) {
|
switch (encoding) {
|
||||||
|
case eEncodingT2:
|
||||||
|
// Ignore bits 15 & 13.
|
||||||
|
registers = EmulateInstruction::UnsignedBits (opcode, 15, 0) & ~0xa000;
|
||||||
|
// if BitCount(registers) < 2 then UNPREDICTABLE;
|
||||||
|
if (BitCount(registers) < 2)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case eEncodingT3:
|
||||||
|
t = EmulateInstruction::UnsignedBits (opcode, 15, 12);
|
||||||
|
// if BadReg(t) then UNPREDICTABLE;
|
||||||
|
if (BadReg(t))
|
||||||
|
return false;
|
||||||
|
registers = (1u << t);
|
||||||
|
break;
|
||||||
case eEncodingA1:
|
case eEncodingA1:
|
||||||
registers = EmulateInstruction::UnsignedBits (opcode, 15, 0);
|
registers = EmulateInstruction::UnsignedBits (opcode, 15, 0);
|
||||||
break;
|
break;
|
||||||
case eEncodingA2:
|
case eEncodingA2:
|
||||||
const uint32_t Rt = EmulateInstruction::UnsignedBits (opcode, 15, 12);
|
t = EmulateInstruction::UnsignedBits (opcode, 15, 12);
|
||||||
// if t == 13 then UNPREDICTABLE
|
// if t == 13 then UNPREDICTABLE;
|
||||||
if (Rt == dwarf_sp)
|
if (t == dwarf_sp)
|
||||||
return false;
|
return false;
|
||||||
registers = (1u << Rt);
|
registers = (1u << t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
addr_t sp_offset = addr_byte_size * EmulateInstruction::BitCount (registers);
|
addr_t sp_offset = addr_byte_size * EmulateInstruction::BitCount (registers);
|
||||||
|
@ -193,9 +215,13 @@ EmulateARMPushEncoding (EmulateInstructionARM *emulator, ARMEncoding encoding)
|
||||||
|
|
||||||
static ARMOpcode g_arm_opcodes[] =
|
static ARMOpcode g_arm_opcodes[] =
|
||||||
{
|
{
|
||||||
{ 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, EmulateARMPushEncoding,
|
{ 0xffff0000, 0xe8ad0000, ARMv6T2|ARMv7, eEncodingT2, eSize32, EmulateARMPushEncoding,
|
||||||
"PUSH<c> <registers> ; <registers> contains more than one register" },
|
"PUSH<c> <registers> ; <registers> contains more than one register" },
|
||||||
{ 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, EmulateARMPushEncoding,
|
{ 0xffff0fff, 0xf84d0d04, ARMv6T2|ARMv7, eEncodingT3, eSize32, EmulateARMPushEncoding,
|
||||||
|
"PUSH<c> <registers> ; <registers> contains one register, <Rt>" },
|
||||||
|
{ 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, eSize32, EmulateARMPushEncoding,
|
||||||
|
"PUSH<c> <registers> ; <registers> contains more than one register" },
|
||||||
|
{ 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, eSize32, EmulateARMPushEncoding,
|
||||||
"PUSH<c> <registers> ; <registers> contains one register, <Rt>" }
|
"PUSH<c> <registers> ; <registers> contains one register, <Rt>" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue