mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 16:24:23 +00:00
The disassembler impl. of MCDisassembler::getInstruction() was using the pattern
uint32_t insn; MemoryObject.readBytes(Address, 4, (uint8_t*)&insn, NULL) to read 4 bytes of memory contents into a 32-bit uint variable. This leaves the interpretation of byte order up to the host machine and causes PPC test cases of arm-tests, neon-tests, and thumb-tests to fail. Fixed to use a byte array for reading the memory contents and shift the bytes into place for the 32-bit uint variable in the ARM case and 16-bit halfword in the Thumb case. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100403 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -380,11 +380,18 @@ bool ARMDisassembler::getInstruction(MCInst &MI,
|
|||||||
raw_ostream &os) const {
|
raw_ostream &os) const {
|
||||||
// The machine instruction.
|
// The machine instruction.
|
||||||
uint32_t insn;
|
uint32_t insn;
|
||||||
|
uint8_t bytes[4];
|
||||||
|
|
||||||
// We want to read exactly 4 bytes of data.
|
// We want to read exactly 4 bytes of data.
|
||||||
if (Region.readBytes(Address, 4, (uint8_t*)&insn, NULL) == -1)
|
if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Encoded as a small-endian 32-bit word in the stream.
|
||||||
|
insn = (bytes[3] << 24) |
|
||||||
|
(bytes[2] << 16) |
|
||||||
|
(bytes[1] << 8) |
|
||||||
|
(bytes[0] << 0);
|
||||||
|
|
||||||
unsigned Opcode = decodeARMInstruction(insn);
|
unsigned Opcode = decodeARMInstruction(insn);
|
||||||
ARMFormat Format = ARMFormats[Opcode];
|
ARMFormat Format = ARMFormats[Opcode];
|
||||||
Size = 4;
|
Size = 4;
|
||||||
@ -414,9 +421,15 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
|
|||||||
const MemoryObject &Region,
|
const MemoryObject &Region,
|
||||||
uint64_t Address,
|
uint64_t Address,
|
||||||
raw_ostream &os) const {
|
raw_ostream &os) const {
|
||||||
// The machine instruction.
|
// The Thumb instruction stream is a sequence of halhwords.
|
||||||
|
|
||||||
|
// This represents the first halfword as well as the machine instruction
|
||||||
|
// passed to decodeThumbInstruction(). For 16-bit Thumb instruction, the top
|
||||||
|
// halfword of insn is 0x00 0x00; otherwise, the first halfword is moved to
|
||||||
|
// the top half followed by the second halfword.
|
||||||
uint32_t insn = 0;
|
uint32_t insn = 0;
|
||||||
uint32_t insn1 = 0;
|
// Possible second halfword.
|
||||||
|
uint16_t insn1 = 0;
|
||||||
|
|
||||||
// A6.1 Thumb instruction set encoding
|
// A6.1 Thumb instruction set encoding
|
||||||
//
|
//
|
||||||
@ -429,9 +442,12 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
|
|||||||
// Otherwise, the halfword is a 16-bit instruction.
|
// Otherwise, the halfword is a 16-bit instruction.
|
||||||
|
|
||||||
// Read 2 bytes of data first.
|
// Read 2 bytes of data first.
|
||||||
if (Region.readBytes(Address, 2, (uint8_t*)&insn, NULL) == -1)
|
uint8_t bytes[2];
|
||||||
|
if (Region.readBytes(Address, 2, (uint8_t*)bytes, NULL) == -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Encoded as a small-endian 16-bit halfword in the stream.
|
||||||
|
insn = (bytes[1] << 8) | bytes[0];
|
||||||
unsigned bits15_11 = slice(insn, 15, 11);
|
unsigned bits15_11 = slice(insn, 15, 11);
|
||||||
bool IsThumb2 = false;
|
bool IsThumb2 = false;
|
||||||
|
|
||||||
@ -439,8 +455,10 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
|
|||||||
// { 0b11101 /* 0x1D */, 0b11110 /* 0x1E */, ob11111 /* 0x1F */ }.
|
// { 0b11101 /* 0x1D */, 0b11110 /* 0x1E */, ob11111 /* 0x1F */ }.
|
||||||
if (bits15_11 == 0x1D || bits15_11 == 0x1E || bits15_11 == 0x1F) {
|
if (bits15_11 == 0x1D || bits15_11 == 0x1E || bits15_11 == 0x1F) {
|
||||||
IsThumb2 = true;
|
IsThumb2 = true;
|
||||||
if (Region.readBytes(Address + 2, 2, (uint8_t*)&insn1, NULL) == -1)
|
if (Region.readBytes(Address + 2, 2, (uint8_t*)bytes, NULL) == -1)
|
||||||
return false;
|
return false;
|
||||||
|
// Encoded as a small-endian 16-bit halfword in the stream.
|
||||||
|
insn1 = (bytes[1] << 8) | bytes[0];
|
||||||
insn = (insn << 16 | insn1);
|
insn = (insn << 16 | insn1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user