summaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-04-06 15:52:58 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-04-06 15:52:58 +0000
commit5f970ec96e421f64db6b1c6509a902ea73d98cc7 (patch)
tree0dd020f28a4846707f8d60717d9b2921ea187bd8 /lib/Target/ARM/Disassembler/ARMDisassembler.cpp
parent62cc576dca6a6aa62c0424f0a1e93a0a679d4c8a (diff)
downloadFreeBSD-src-5f970ec96e421f64db6b1c6509a902ea73d98cc7.zip
FreeBSD-src-5f970ec96e421f64db6b1c6509a902ea73d98cc7.tar.gz
Update LLVM to r100520.
Diffstat (limited to 'lib/Target/ARM/Disassembler/ARMDisassembler.cpp')
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassembler.cpp28
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 0431340..47c3104 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -380,11 +380,18 @@ bool ARMDisassembler::getInstruction(MCInst &MI,
raw_ostream &os) const {
// The machine instruction.
uint32_t insn;
+ uint8_t bytes[4];
// 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;
+ // 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);
ARMFormat Format = ARMFormats[Opcode];
Size = 4;
@@ -414,9 +421,15 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
const MemoryObject &Region,
uint64_t Address,
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 insn1 = 0;
+ // Possible second halfword.
+ uint16_t insn1 = 0;
// A6.1 Thumb instruction set encoding
//
@@ -429,9 +442,12 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
// Otherwise, the halfword is a 16-bit instruction.
// 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;
+ // Encoded as a small-endian 16-bit halfword in the stream.
+ insn = (bytes[1] << 8) | bytes[0];
unsigned bits15_11 = slice(insn, 15, 11);
bool IsThumb2 = false;
@@ -439,8 +455,10 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
// { 0b11101 /* 0x1D */, 0b11110 /* 0x1E */, ob11111 /* 0x1F */ }.
if (bits15_11 == 0x1D || bits15_11 == 0x1E || bits15_11 == 0x1F) {
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;
+ // Encoded as a small-endian 16-bit halfword in the stream.
+ insn1 = (bytes[1] << 8) | bytes[0];
insn = (insn << 16 | insn1);
}
OpenPOWER on IntegriCloud