[PPC] Disassemble little endian ppc instructions in the right byte order

PR24122. The test is simply a byte swapped version of ppc64-encoding.txt.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242288 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer
2015-07-15 12:56:19 +00:00
parent 4aa2f4514c
commit 17351cfb43
2 changed files with 681 additions and 8 deletions

View File

@@ -12,6 +12,7 @@
#include "llvm/MC/MCFixedLenDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
@@ -22,10 +23,12 @@ typedef MCDisassembler::DecodeStatus DecodeStatus;
namespace {
class PPCDisassembler : public MCDisassembler {
bool IsLittleEndian;
public:
PPCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
: MCDisassembler(STI, Ctx) {}
~PPCDisassembler() override {}
PPCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
bool IsLittleEndian)
: MCDisassembler(STI, Ctx), IsLittleEndian(IsLittleEndian) {}
DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
ArrayRef<uint8_t> Bytes, uint64_t Address,
@@ -37,7 +40,13 @@ public:
static MCDisassembler *createPPCDisassembler(const Target &T,
const MCSubtargetInfo &STI,
MCContext &Ctx) {
return new PPCDisassembler(STI, Ctx);
return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/false);
}
static MCDisassembler *createPPCLEDisassembler(const Target &T,
const MCSubtargetInfo &STI,
MCContext &Ctx) {
return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/true);
}
extern "C" void LLVMInitializePowerPCDisassembler() {
@@ -47,7 +56,7 @@ extern "C" void LLVMInitializePowerPCDisassembler() {
TargetRegistry::RegisterMCDisassembler(ThePPC64Target,
createPPCDisassembler);
TargetRegistry::RegisterMCDisassembler(ThePPC64LETarget,
createPPCDisassembler);
createPPCLEDisassembler);
}
// FIXME: These can be generated by TableGen from the existing register
@@ -383,9 +392,9 @@ DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
return MCDisassembler::Fail;
}
// The instruction is big-endian encoded.
uint32_t Inst =
(Bytes[0] << 24) | (Bytes[1] << 16) | (Bytes[2] << 8) | (Bytes[3] << 0);
// Read the instruction in the proper endianness.
uint32_t Inst = IsLittleEndian ? support::endian::read32le(Bytes.data())
: support::endian::read32be(Bytes.data());
if (STI.getFeatureBits()[PPC::FeatureQPX]) {
DecodeStatus result =