From 7b9135922626f04652da8d8e5312fe9193d891d9 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228825 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Mips/Disassembler/MipsDisassembler.cpp | 106 ++++-------------- .../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, 32 insertions(+), 86 deletions(-) diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index c8a5195e8e6..8849366e837 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -30,33 +30,14 @@ typedef MCDisassembler::DecodeStatus DecodeStatus; namespace { -/// A disassembler class for Mips. -class MipsDisassemblerBase : public MCDisassembler { -public: - MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx, - bool IsBigEndian) - : MCDisassembler(STI, Ctx), - IsGP64Bit(STI.getFeatureBits() & Mips::FeatureGP64Bit), - IsBigEndian(IsBigEndian) {} - - virtual ~MipsDisassemblerBase() {} - - bool isGP64Bit() const { return IsGP64Bit; } - -private: - bool IsGP64Bit; -protected: - bool IsBigEndian; -}; - -/// A disassembler class for Mips32. -class MipsDisassembler : public MipsDisassemblerBase { +class MipsDisassembler : public MCDisassembler { bool IsMicroMips; + bool IsBigEndian; public: - MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool bigEndian) - : MipsDisassemblerBase(STI, Ctx, bigEndian) { - IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips; - } + MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian) + : MCDisassembler(STI, Ctx), + IsMicroMips(STI.getFeatureBits() & Mips::FeatureMicroMips), + IsBigEndian(IsBigEndian) {} bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; } bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; } @@ -77,19 +58,6 @@ public: 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,6 +882,16 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, } } + 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; + } + } + DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n"); // Calling the auto-generated decoder function. Result = @@ -940,36 +904,6 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 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; - - // 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) { - Size = 4; - return Result; - } - - return MCDisassembler::Fail; -} - static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -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/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2-le.txt b/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2-le.txt index a946ad0351f..d0eb13c5afd 100644 --- a/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2-le.txt +++ b/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/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2.txt b/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2.txt index ec75a2ea9d6..96378357d19 100644 --- a/test/MC/Disassembler/Mips/mips32r2/valid-mips32r2.txt +++ b/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/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2-el.txt b/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2-el.txt index 405222e0f61..6509456b07e 100644 --- a/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2-el.txt +++ b/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/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2.txt b/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2.txt index d364238e885..9fc9f6e6bb0 100644 --- a/test/MC/Disassembler/Mips/mips64r2/valid-mips64r2.txt +++ b/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