mirror of
https://github.com/intel/llvm.git
synced 2026-01-15 12:25:46 +08:00
Fixed an error in the thumb opcode encoding. We need the 32 bit thumb instructions to be encoded as a 32 bit value for the EmulateARM code.
llvm-svn: 161381
This commit is contained in:
@@ -41,12 +41,6 @@ Opcode::Dump (Stream *s, uint32_t min_byte_width)
|
||||
bytes_written = s->Printf ("0x%4.4x", m_data.inst16);
|
||||
break;
|
||||
case Opcode::eType16_2:
|
||||
if (GetDataByteOrder() == eByteOrderLittle)
|
||||
bytes_written = s->Printf ("0x%4.4x%4.4x", m_data.inst32 & 0xffff, m_data.inst32 >> 16);
|
||||
else
|
||||
bytes_written = s->Printf ("0x%2.2x%2.2x%2.2x%2.2x", (m_data.inst32 >> 16) & 0xff, (m_data.inst32 >> 24),
|
||||
(m_data.inst32 & 0xff), (m_data.inst32 >> 8) & 0xff);
|
||||
break;
|
||||
case Opcode::eType32:
|
||||
bytes_written = s->Printf ("0x%8.8x", m_data.inst32);
|
||||
break;
|
||||
@@ -106,8 +100,27 @@ Opcode::GetData (DataExtractor &data, lldb::AddressClass address_class) const
|
||||
|
||||
case Opcode::eType8: buffer_sp.reset (new DataBufferHeap (&m_data.inst8, byte_size)); break;
|
||||
case Opcode::eType16: buffer_sp.reset (new DataBufferHeap (&m_data.inst16, byte_size)); break;
|
||||
case Opcode::eType16_2: // passthrough
|
||||
case Opcode::eType32: buffer_sp.reset (new DataBufferHeap (&m_data.inst32, byte_size)); break;
|
||||
case Opcode::eType16_2:
|
||||
case Opcode::eType32:
|
||||
// The only thing that uses eAddressClassCodeAlternateISA currently
|
||||
// is Thumb. If this ever changes, we will need to pass in more
|
||||
// information like an additional "const ArchSpec &arch". For now
|
||||
// this will do
|
||||
if (m_type == Opcode::eType16_2 || address_class == eAddressClassCodeAlternateISA)
|
||||
{
|
||||
// 32 bit thumb instruction, we need to sizzle this a bit
|
||||
uint8_t buf[4];
|
||||
buf[0] = m_data.inst.bytes[2];
|
||||
buf[1] = m_data.inst.bytes[3];
|
||||
buf[2] = m_data.inst.bytes[0];
|
||||
buf[3] = m_data.inst.bytes[1];
|
||||
buffer_sp.reset (new DataBufferHeap (buf, byte_size));
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer_sp.reset (new DataBufferHeap (&m_data.inst32, byte_size));
|
||||
}
|
||||
break;
|
||||
case Opcode::eType64: buffer_sp.reset (new DataBufferHeap (&m_data.inst64, byte_size)); break;
|
||||
case Opcode::eTypeBytes:buffer_sp.reset (new DataBufferHeap (GetOpcodeBytes(), byte_size)); break;
|
||||
break;
|
||||
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
{
|
||||
if (machine == llvm::Triple::thumb || is_altnernate_isa)
|
||||
{
|
||||
uint16_t thumb_opcode = data.GetU16(&data_offset);
|
||||
uint32_t thumb_opcode = data.GetU16(&data_offset);
|
||||
if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
|
||||
{
|
||||
m_opcode.SetOpcode16 (thumb_opcode);
|
||||
@@ -138,8 +138,9 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
data_offset -= 2;
|
||||
m_opcode.SetOpcode16_2 (data.GetU32(&data_offset));
|
||||
thumb_opcode <<= 16;
|
||||
thumb_opcode |= data.GetU16(&data_offset);
|
||||
m_opcode.SetOpcode16_2 (thumb_opcode);
|
||||
m_is_valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user