mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-06 01:24:35 +00:00
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:
@ -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,
|
||||
|
Reference in New Issue
Block a user