Skip to content

Commit

Permalink
[mips] Merge disassemblers into a single implementation.
Browse files Browse the repository at this point in the history
Summary:
Currently we have Mips32 and Mips64 disassemblers and this causes the target
triple to affect the disassembly despite all the relevant information being in
the ELF header. These implementations do not need to be separate.

This patch merges them together such that the appropriate tables are checked
for the subtarget (e.g. Mips64 is checked when GP64 is enabled).

Reviewers: vmedic

Reviewed By: vmedic

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D7498

llvm-svn: 228825
  • Loading branch information
dsandersllvm committed Feb 11, 2015
1 parent 333fc18 commit a19216c
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 84 deletions.
102 changes: 18 additions & 84 deletions llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
Expand Up @@ -30,34 +30,15 @@ typedef MCDisassembler::DecodeStatus DecodeStatus;

namespace {

/// A disassembler class for Mips.
class MipsDisassemblerBase : public MCDisassembler {
class MipsDisassembler : public MCDisassembler {
bool IsMicroMips;
bool IsBigEndian;
public:
MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx,
bool IsBigEndian)
MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
: MCDisassembler(STI, Ctx),
IsGP64Bit(STI.getFeatureBits() & Mips::FeatureGP64Bit),
IsMicroMips(STI.getFeatureBits() & Mips::FeatureMicroMips),
IsBigEndian(IsBigEndian) {}

virtual ~MipsDisassemblerBase() {}

bool isGP64Bit() const { return IsGP64Bit; }

private:
bool IsGP64Bit;
protected:
bool IsBigEndian;
};

/// A disassembler class for Mips32.
class MipsDisassembler : public MipsDisassemblerBase {
bool IsMicroMips;
public:
MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool bigEndian)
: MipsDisassemblerBase(STI, Ctx, bigEndian) {
IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
}

bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; }
bool hasMips32r6() const {
Expand All @@ -77,19 +58,6 @@ class MipsDisassembler : public MipsDisassemblerBase {
raw_ostream &CStream) const override;
};

/// A disassembler class for Mips64.
class Mips64Disassembler : public MipsDisassemblerBase {
public:
Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
bool bigEndian) :
MipsDisassemblerBase(STI, Ctx, bigEndian) {}

DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
ArrayRef<uint8_t> Bytes, uint64_t Address,
raw_ostream &VStream,
raw_ostream &CStream) const override;
};

} // end anonymous namespace

// Forward declare these because the autogenerated code will reference them.
Expand Down Expand Up @@ -467,36 +435,22 @@ static MCDisassembler *createMipselDisassembler(
return new MipsDisassembler(STI, Ctx, false);
}

static MCDisassembler *createMips64Disassembler(
const Target &T,
const MCSubtargetInfo &STI,
MCContext &Ctx) {
return new Mips64Disassembler(STI, Ctx, true);
}

static MCDisassembler *createMips64elDisassembler(
const Target &T,
const MCSubtargetInfo &STI,
MCContext &Ctx) {
return new Mips64Disassembler(STI, Ctx, false);
}

extern "C" void LLVMInitializeMipsDisassembler() {
// Register the disassembler.
TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
createMipsDisassembler);
TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
createMipselDisassembler);
TargetRegistry::RegisterMCDisassembler(TheMips64Target,
createMips64Disassembler);
createMipsDisassembler);
TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
createMips64elDisassembler);
createMipselDisassembler);
}

#include "MipsGenDisassemblerTables.inc"

static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
return *(RegInfo->getRegClass(RC).begin() + RegNo);
}
Expand Down Expand Up @@ -928,38 +882,18 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
}
}

DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
// Calling the auto-generated decoder function.
Result =
decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
return Result;
if (isGP64()) {
DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
Address, this, STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
return Result;
}
}

return MCDisassembler::Fail;
}

DecodeStatus Mips64Disassembler::getInstruction(MCInst &Instr, uint64_t &Size,
ArrayRef<uint8_t> Bytes,
uint64_t Address,
raw_ostream &VStream,
raw_ostream &CStream) const {
uint32_t Insn;

DecodeStatus Result =
readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
if (Result == MCDisassembler::Fail)
return MCDisassembler::Fail;

DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
// Calling the auto-generated decoder function.
Result =
decodeInstruction(DecoderTableMips6432, Instr, Insn, Address, this, STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
return Result;
}
// If we fail to decode in Mips64 decoder space we can try in Mips32
Result =
decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
if (Result != MCDisassembler::Fail) {
Expand Down Expand Up @@ -1040,7 +974,7 @@ static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder) {
if (static_cast<const MipsDisassembler *>(Decoder)->isGP64Bit())
if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);

return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2-le.txt
@@ -1,4 +1,7 @@
# RUN: llvm-mc --disassemble %s -triple=mipsel-unknown-linux -mcpu=mips32r2 | FileCheck %s
# Try a mips64* triple to confirm that mips* vs mips64* triples no longer have
# an effect on the disassembler behaviour.
# RUN: llvm-mc --disassemble %s -triple=mips64el-unknown-linux -mcpu=mips32r2 | FileCheck %s
0x05 0x73 0x20 0x46 # CHECK: abs.d $f12, $f14
0x85 0x39 0x00 0x46 # CHECK: abs.s $f6, $f7
0x20 0x48 0xc7 0x00 # CHECK: add $9, $6, $7
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2.txt
@@ -1,4 +1,7 @@
# RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux -mcpu=mips32r2 | FileCheck %s
# Try a mips64* triple to confirm that mips* vs mips64* triples no longer have
# an effect on the disassembler behaviour.
# RUN: llvm-mc --disassemble %s -triple=mips64-unknown-linux -mcpu=mips32r2 | FileCheck %s
0x46 0x20 0x73 0x05 # CHECK: abs.d $f12, $f14
0x46 0x00 0x39 0x85 # CHECK: abs.s $f6, $f7
0x00 0xc7 0x48 0x20 # CHECK: add $9, $6, $7
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2-el.txt
@@ -1,4 +1,7 @@
# RUN: llvm-mc --disassemble %s -triple=mips64el-unknown-linux -mcpu=mips64r2 | FileCheck %s
# Try a mips* triple to confirm that mips* vs mips64* triples no longer have
# an effect on the disassembler behaviour.
# RUN: llvm-mc --disassemble %s -triple=mipsel-unknown-linux -mcpu=mips64r2 | FileCheck %s
# CHECK: .text
0x05 0x73 0x20 0x46 # CHECK: abs.d $f12, $f14
0x85 0x39 0x00 0x46 # CHECK: abs.s $f6, $f7
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2.txt
@@ -1,4 +1,7 @@
# RUN: llvm-mc --disassemble %s -triple=mips64-unknown-linux -mcpu=mips64r2 | FileCheck %s
# Try a mips* triple to confirm that mips* vs mips64* triples no longer have
# an effect on the disassembler behaviour.
# RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux -mcpu=mips64r2 | FileCheck %s
# CHECK: .text
0x46 0x20 0x73 0x05 # CHECK: abs.d $f12, $f14
0x46 0x00 0x39 0x85 # CHECK: abs.s $f6, $f7
Expand Down

0 comments on commit a19216c

Please sign in to comment.