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
This commit is contained in:
Vladimir Medic
2013-09-06 12:30:36 +00:00
parent 99d02d1325
commit a674463aac
4 changed files with 391 additions and 17 deletions

View File

@ -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 &region,
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 &region,
}
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,