From a674463aac1d0b5d039da11045ccfab5e849b886 Mon Sep 17 00:00:00 2001 From: Vladimir Medic Date: Fri, 6 Sep 2013 12:30:36 +0000 Subject: This patch adds support for microMIPS disassembler and disassembler make check tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190144 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 87 ++++++++++++++++++++--- 1 file changed, 79 insertions(+), 8 deletions(-) (limited to 'lib/Target/Mips/Disassembler') diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 6e12a5d5e5..e2b3fa4182 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -53,12 +53,15 @@ protected: /// MipsDisassembler - a disasembler class for Mips32. class MipsDisassembler : public MipsDisassemblerBase { + bool IsMicroMips; public: /// Constructor - Initializes the disassembler. /// MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, bool bigEndian) : - MipsDisassemblerBase(STI, Info, bigEndian) {} + MipsDisassemblerBase(STI, Info, bigEndian) { + IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips; + } /// getInstruction - See MCDisassembler. virtual DecodeStatus getInstruction(MCInst &instr, @@ -182,6 +185,16 @@ static DecodeStatus DecodeMem(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMemMMImm12(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeMemMMImm16(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); @@ -251,7 +264,8 @@ static DecodeStatus readInstruction32(const MemoryObject ®ion, uint64_t address, uint64_t &size, uint32_t &insn, - bool isBigEndian) { + bool isBigEndian, + bool IsMicroMips) { uint8_t Bytes[4]; // We want to read exactly 4 Bytes of data. @@ -269,10 +283,20 @@ static DecodeStatus readInstruction32(const MemoryObject ®ion, } else { // Encoded as a small-endian 32-bit word in the stream. - insn = (Bytes[0] << 0) | - (Bytes[1] << 8) | - (Bytes[2] << 16) | - (Bytes[3] << 24); + // Little-endian byte ordering: + // mips32r2: 4 | 3 | 2 | 1 + // microMIPS: 2 | 1 | 4 | 3 + if (IsMicroMips) { + insn = (Bytes[2] << 0) | + (Bytes[3] << 8) | + (Bytes[0] << 16) | + (Bytes[1] << 24); + } else { + insn = (Bytes[0] << 0) | + (Bytes[1] << 8) | + (Bytes[2] << 16) | + (Bytes[3] << 24); + } } return MCDisassembler::Success; @@ -288,10 +312,21 @@ MipsDisassembler::getInstruction(MCInst &instr, uint32_t Insn; DecodeStatus Result = readInstruction32(Region, Address, Size, - Insn, isBigEndian); + Insn, isBigEndian, IsMicroMips); if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; + if (IsMicroMips) { + // Calling the auto-generated decoder function. + Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address, + this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } + return MCDisassembler::Fail; + } + // Calling the auto-generated decoder function. Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, this, STI); @@ -313,7 +348,7 @@ Mips64Disassembler::getInstruction(MCInst &instr, uint32_t Insn; DecodeStatus Result = readInstruction32(Region, Address, Size, - Insn, isBigEndian); + Insn, isBigEndian, false); if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; @@ -470,6 +505,42 @@ static DecodeStatus DecodeMem(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeMemMMImm12(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<12>(Insn & 0x0fff); + unsigned Reg = fieldFromInstruction(Insn, 21, 5); + unsigned Base = fieldFromInstruction(Insn, 16, 5); + + Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + + Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::CreateReg(Base)); + Inst.addOperand(MCOperand::CreateImm(Offset)); + + return MCDisassembler::Success; +} + +static DecodeStatus DecodeMemMMImm16(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<16>(Insn & 0xffff); + unsigned Reg = fieldFromInstruction(Insn, 21, 5); + unsigned Base = fieldFromInstruction(Insn, 16, 5); + + Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + + Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::CreateReg(Base)); + Inst.addOperand(MCOperand::CreateImm(Offset)); + + return MCDisassembler::Success; +} + static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address, -- cgit v1.2.3