From a19216c8f4b26cb98aae5ada5c44c73bd3bf350e Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Wed, 11 Feb 2015 11:28:56 +0000 Subject: [PATCH] [mips] Merge disassemblers into a single implementation. 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 --- .../Mips/Disassembler/MipsDisassembler.cpp | 102 ++++-------------- .../Mips/mips32r2/valid-mips32r2-le.txt | 3 + .../Mips/mips32r2/valid-mips32r2.txt | 3 + .../Mips/mips64r2/valid-mips64r2-el.txt | 3 + .../Mips/mips64r2/valid-mips64r2.txt | 3 + 5 files changed, 30 insertions(+), 84 deletions(-) diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index c8a5195e8e686..8849366e8371e 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -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 { @@ -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 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. @@ -467,20 +435,6 @@ 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, @@ -488,15 +442,15 @@ extern "C" void LLVMInitializeMipsDisassembler() { 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(D); + const MipsDisassembler *Dis = static_cast(D); const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo(); return *(RegInfo->getRegClass(RC).begin() + RegNo); } @@ -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 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) { @@ -1040,7 +974,7 @@ static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { - if (static_cast(Decoder)->isGP64Bit()) + if (static_cast(Decoder)->isGP64()) return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); diff --git a/llvm/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2-le.txt b/llvm/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2-le.txt index a946ad0351f6d..d0eb13c5afd5e 100644 --- a/llvm/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2-le.txt +++ b/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 diff --git a/llvm/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2.txt b/llvm/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2.txt index ec75a2ea9d61a..96378357d19bd 100644 --- a/llvm/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2.txt +++ b/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 diff --git a/llvm/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2-el.txt b/llvm/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2-el.txt index 405222e0f6139..6509456b07eeb 100644 --- a/llvm/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2-el.txt +++ b/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 diff --git a/llvm/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2.txt b/llvm/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2.txt index d364238e885ba..9fc9f6e6bb046 100644 --- a/llvm/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2.txt +++ b/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