X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTarget%2FMips%2FDisassembler%2FMipsDisassembler.cpp;h=cbf9e1356bc5752b380c61edb2b79be07e6ce818;hp=d733b1b85d63348d5c541704af4adc38621a5d67;hb=3acfef5bd33f0d72f71c58ca9803ab49a4dddc88;hpb=d342c4c748248b90cb2a0618b70f0abbe185afa7 diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index d733b1b85d6..cbf9e1356bc 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -20,7 +20,6 @@ #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/MathExtras.h" -#include "llvm/Support/MemoryObject.h" #include "llvm/Support/TargetRegistry.h" using namespace llvm; @@ -31,41 +30,24 @@ typedef MCDisassembler::DecodeStatus DecodeStatus; namespace { -/// A disasembler 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), - IsN64(STI.getFeatureBits() & Mips::FeatureN64), + IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]), IsBigEndian(IsBigEndian) {} - virtual ~MipsDisassemblerBase() {} - - bool isN64() const { return IsN64; } - -private: - bool IsN64; -protected: - bool IsBigEndian; -}; - -/// A disasembler 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 hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; } + bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; } bool hasMips32r6() const { - return STI.getFeatureBits() & Mips::FeatureMips32r6; + return STI.getFeatureBits()[Mips::FeatureMips32r6]; } - bool isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; } + bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; } + + bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; } bool hasCOP3() const { // Only present in MIPS-I and MIPS-II @@ -73,20 +55,7 @@ public: } DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, - const MemoryObject &Region, uint64_t Address, - raw_ostream &VStream, - raw_ostream &CStream) const override; -}; - -/// A disasembler 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, - const MemoryObject &Region, uint64_t Address, + ArrayRef Bytes, uint64_t Address, raw_ostream &VStream, raw_ostream &CStream) const override; }; @@ -110,6 +79,16 @@ static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -199,6 +178,11 @@ static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -224,6 +208,20 @@ static DecodeStatus DecodeBranchTarget26(MCInst &Inst, uint64_t Address, const void *Decoder); +// DecodeBranchTarget7MM - Decode microMIPS branch offset, which is +// shifted left by 1 bit. +static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder); + +// DecodeBranchTarget10MM - Decode microMIPS branch offset, which is +// shifted left by 1 bit. +static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder); + // DecodeBranchTargetMM - Decode microMIPS branch offset, which is // shifted left by 1 bit. static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, @@ -248,9 +246,54 @@ static DecodeStatus DecodeCacheOp(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeCacheOpR6(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeCacheOpMM(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeSyncI(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMemMMImm4(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeMemMMImm9(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -273,11 +316,35 @@ static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, + unsigned Value, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, + unsigned Value, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeLiSimm7(MCInst &Inst, + unsigned Value, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeSimm4(MCInst &Inst, + unsigned Value, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeSimm16(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -306,6 +373,18 @@ static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't /// handle. template @@ -342,6 +421,18 @@ static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn, + uint64_t Address, + const void *Decoder); + namespace llvm { extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, TheMips64elTarget; @@ -361,20 +452,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, @@ -382,15 +459,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); } @@ -430,13 +507,13 @@ static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, return MCDisassembler::Fail; // $n tmp = fieldFromInstruction(insn, 16, NSize); - MI.addOperand(MCOperand::CreateImm(tmp)); + MI.addOperand(MCOperand::createImm(tmp)); // $ws tmp = fieldFromInstruction(insn, 11, 5); if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) return MCDisassembler::Fail; // $n2 - MI.addOperand(MCOperand::CreateImm(0)); + MI.addOperand(MCOperand::createImm(0)); return MCDisassembler::Success; } @@ -470,12 +547,12 @@ static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, MI.setOpcode(Mips::BEQZALC); if (HasRs) - MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); - MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); - MI.addOperand(MCOperand::CreateImm(Imm)); + MI.addOperand(MCOperand::createImm(Imm)); return MCDisassembler::Success; } @@ -509,12 +586,12 @@ static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, MI.setOpcode(Mips::BNEZALC); if (HasRs) - MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); - MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); - MI.addOperand(MCOperand::CreateImm(Imm)); + MI.addOperand(MCOperand::createImm(Imm)); return MCDisassembler::Success; } @@ -551,13 +628,13 @@ static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, } if (HasRs) - MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); - MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); - MI.addOperand(MCOperand::CreateImm(Imm)); + MI.addOperand(MCOperand::createImm(Imm)); return MCDisassembler::Success; } @@ -595,13 +672,13 @@ static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, } if (HasRs) - MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); - MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); - MI.addOperand(MCOperand::CreateImm(Imm)); + MI.addOperand(MCOperand::createImm(Imm)); return MCDisassembler::Success; } @@ -643,14 +720,14 @@ static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, } if (HasRs) - MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); if (HasRt) - MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); - MI.addOperand(MCOperand::CreateImm(Imm)); + MI.addOperand(MCOperand::createImm(Imm)); return MCDisassembler::Success; } @@ -687,39 +764,60 @@ static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn, } if (HasRs) - MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); - MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); - MI.addOperand(MCOperand::CreateImm(Imm)); + MI.addOperand(MCOperand::createImm(Imm)); return MCDisassembler::Success; } -/// Read four bytes from the MemoryObject and return 32 bit word sorted -/// according to the given endianess -static DecodeStatus readInstruction32(const MemoryObject &Region, - uint64_t Address, uint64_t &Size, - uint32_t &Insn, bool IsBigEndian, - bool IsMicroMips) { - uint8_t Bytes[4]; +/// Read two bytes from the ArrayRef and return 16 bit halfword sorted +/// according to the given endianess. +static DecodeStatus readInstruction16(ArrayRef Bytes, uint64_t Address, + uint64_t &Size, uint32_t &Insn, + bool IsBigEndian) { + // We want to read exactly 2 Bytes of data. + if (Bytes.size() < 2) { + Size = 0; + return MCDisassembler::Fail; + } + if (IsBigEndian) { + Insn = (Bytes[0] << 8) | Bytes[1]; + } else { + Insn = (Bytes[1] << 8) | Bytes[0]; + } + + return MCDisassembler::Success; +} + +/// Read four bytes from the ArrayRef and return 32 bit word sorted +/// according to the given endianess +static DecodeStatus readInstruction32(ArrayRef Bytes, uint64_t Address, + uint64_t &Size, uint32_t &Insn, + bool IsBigEndian, bool IsMicroMips) { // We want to read exactly 4 Bytes of data. - if (Region.readBytes(Address, 4, Bytes) == -1) { + if (Bytes.size() < 4) { Size = 0; return MCDisassembler::Fail; } + // High 16 bits of a 32-bit microMIPS instruction (where the opcode is) + // always precede the low 16 bits in the instruction stream (that is, they + // are placed at lower addresses in the instruction stream). + // + // microMIPS byte ordering: + // Big-endian: 0 | 1 | 2 | 3 + // Little-endian: 1 | 0 | 3 | 2 + if (IsBigEndian) { // Encoded as a big-endian 32-bit word in the stream. Insn = (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24); } else { - // Encoded as a small-endian 32-bit word in the stream. - // 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); @@ -733,19 +831,54 @@ static DecodeStatus readInstruction32(const MemoryObject &Region, } DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, - const MemoryObject &Region, + ArrayRef Bytes, uint64_t Address, raw_ostream &VStream, raw_ostream &CStream) const { uint32_t Insn; - - DecodeStatus Result = - readInstruction32(Region, Address, Size, Insn, IsBigEndian, IsMicroMips); - if (Result == MCDisassembler::Fail) - return MCDisassembler::Fail; + DecodeStatus Result; if (IsMicroMips) { - DEBUG(dbgs() << "Trying MicroMips32 table (32-bit opcodes):\n"); + Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); + + if (hasMips32r6()) { + DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n"); + // Calling the auto-generated decoder function for microMIPS32R6 + // (and microMIPS64R6) 16-bit instructions. + Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn, + Address, this, STI); + if (Result != MCDisassembler::Fail) { + Size = 2; + return Result; + } + } + + DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n"); + // Calling the auto-generated decoder function for microMIPS 16-bit + // instructions. + Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address, + this, STI); + if (Result != MCDisassembler::Fail) { + Size = 2; + return Result; + } + + Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true); + if (Result == MCDisassembler::Fail) + return MCDisassembler::Fail; + + if (hasMips32r6()) { + DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n"); + // Calling the auto-generated decoder function. + Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address, + this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } + } + + DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); // Calling the auto-generated decoder function. Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, this, STI); @@ -756,6 +889,10 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, return MCDisassembler::Fail; } + Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); + if (Result == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (hasCOP3()) { DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n"); Result = @@ -786,38 +923,28 @@ 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 (hasCnMips()) { + DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n"); + Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn, + Address, this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } } - return MCDisassembler::Fail; -} - -DecodeStatus Mips64Disassembler::getInstruction(MCInst &Instr, uint64_t &Size, - const MemoryObject &Region, - uint64_t Address, - raw_ostream &VStream, - raw_ostream &CStream) const { - uint32_t Insn; - - DecodeStatus Result = - readInstruction32(Region, Address, Size, Insn, IsBigEndian, false); - if (Result == MCDisassembler::Fail) - return MCDisassembler::Fail; + 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 = - 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) { @@ -846,7 +973,7 @@ static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -854,7 +981,33 @@ static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { - return MCDisassembler::Fail; + if (RegNo > 7) + return MCDisassembler::Fail; + unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 7) + return MCDisassembler::Fail; + unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 7) + return MCDisassembler::Fail; + unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; } static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, @@ -864,7 +1017,7 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, if (RegNo > 31) return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -872,7 +1025,7 @@ static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { - if (static_cast(Decoder)->isN64()) + if (static_cast(Decoder)->isGP64()) return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); @@ -893,7 +1046,7 @@ static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -905,7 +1058,7 @@ static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -916,7 +1069,7 @@ static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, if (RegNo > 31) return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -927,7 +1080,7 @@ static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, if (RegNo > 7) return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -938,7 +1091,7 @@ static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -953,13 +1106,14 @@ static DecodeStatus DecodeMem(MCInst &Inst, Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); Base = getReg(Decoder, Mips::GPR32RegClassID, Base); - if(Inst.getOpcode() == Mips::SC){ - Inst.addOperand(MCOperand::CreateReg(Reg)); + if(Inst.getOpcode() == Mips::SC || + Inst.getOpcode() == Mips::SCD){ + Inst.addOperand(MCOperand::createReg(Reg)); } - Inst.addOperand(MCOperand::CreateReg(Reg)); - Inst.addOperand(MCOperand::CreateReg(Base)); - Inst.addOperand(MCOperand::CreateImm(Offset)); + Inst.addOperand(MCOperand::createReg(Reg)); + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); return MCDisassembler::Success; } @@ -974,9 +1128,76 @@ static DecodeStatus DecodeCacheOp(MCInst &Inst, Base = getReg(Decoder, Mips::GPR32RegClassID, Base); - Inst.addOperand(MCOperand::CreateReg(Base)); - Inst.addOperand(MCOperand::CreateImm(Offset)); - Inst.addOperand(MCOperand::CreateImm(Hint)); + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); + Inst.addOperand(MCOperand::createImm(Hint)); + + return MCDisassembler::Success; +} + +static DecodeStatus DecodeCacheOpMM(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<12>(Insn & 0xfff); + unsigned Base = fieldFromInstruction(Insn, 16, 5); + unsigned Hint = fieldFromInstruction(Insn, 21, 5); + + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); + Inst.addOperand(MCOperand::createImm(Hint)); + + return MCDisassembler::Success; +} + +static DecodeStatus DecodeCacheOpR6(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = fieldFromInstruction(Insn, 7, 9); + unsigned Hint = fieldFromInstruction(Insn, 16, 5); + unsigned Base = fieldFromInstruction(Insn, 21, 5); + + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); + Inst.addOperand(MCOperand::createImm(Hint)); + + return MCDisassembler::Success; +} + +static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<9>(Insn & 0x1ff); + 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 DecodeSyncI(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<16>(Insn & 0xffff); + unsigned Base = fieldFromInstruction(Insn, 21, 5); + + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); return MCDisassembler::Success; } @@ -990,8 +1211,8 @@ static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg); Base = getReg(Decoder, Mips::GPR32RegClassID, Base); - Inst.addOperand(MCOperand::CreateReg(Reg)); - Inst.addOperand(MCOperand::CreateReg(Base)); + Inst.addOperand(MCOperand::createReg(Reg)); + Inst.addOperand(MCOperand::createReg(Base)); // The immediate field of an LD/ST instruction is scaled which means it must // be multiplied (when decoding) by the size (in bytes) of the instructions' @@ -1008,25 +1229,143 @@ static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, break; case Mips::LD_B: case Mips::ST_B: - Inst.addOperand(MCOperand::CreateImm(Offset)); + Inst.addOperand(MCOperand::createImm(Offset)); break; case Mips::LD_H: case Mips::ST_H: - Inst.addOperand(MCOperand::CreateImm(Offset * 2)); + Inst.addOperand(MCOperand::createImm(Offset * 2)); break; case Mips::LD_W: case Mips::ST_W: - Inst.addOperand(MCOperand::CreateImm(Offset * 4)); + Inst.addOperand(MCOperand::createImm(Offset * 4)); break; case Mips::LD_D: case Mips::ST_D: - Inst.addOperand(MCOperand::CreateImm(Offset * 8)); + Inst.addOperand(MCOperand::createImm(Offset * 8)); break; } return MCDisassembler::Success; } +static DecodeStatus DecodeMemMMImm4(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + unsigned Offset = Insn & 0xf; + unsigned Reg = fieldFromInstruction(Insn, 7, 3); + unsigned Base = fieldFromInstruction(Insn, 4, 3); + + switch (Inst.getOpcode()) { + case Mips::LBU16_MM: + case Mips::LHU16_MM: + case Mips::LW16_MM: + if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder) + == MCDisassembler::Fail) + return MCDisassembler::Fail; + break; + case Mips::SB16_MM: + case Mips::SH16_MM: + case Mips::SW16_MM: + if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder) + == MCDisassembler::Fail) + return MCDisassembler::Fail; + break; + } + + if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder) + == MCDisassembler::Fail) + return MCDisassembler::Fail; + + switch (Inst.getOpcode()) { + case Mips::LBU16_MM: + if (Offset == 0xf) + Inst.addOperand(MCOperand::createImm(-1)); + else + Inst.addOperand(MCOperand::createImm(Offset)); + break; + case Mips::SB16_MM: + Inst.addOperand(MCOperand::createImm(Offset)); + break; + case Mips::LHU16_MM: + case Mips::SH16_MM: + Inst.addOperand(MCOperand::createImm(Offset << 1)); + break; + case Mips::LW16_MM: + case Mips::SW16_MM: + Inst.addOperand(MCOperand::createImm(Offset << 2)); + break; + } + + return MCDisassembler::Success; +} + +static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + unsigned Offset = Insn & 0x1F; + unsigned Reg = fieldFromInstruction(Insn, 5, 5); + + Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); + + Inst.addOperand(MCOperand::createReg(Reg)); + Inst.addOperand(MCOperand::createReg(Mips::SP)); + Inst.addOperand(MCOperand::createImm(Offset << 2)); + + return MCDisassembler::Success; +} + +static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + unsigned Offset = Insn & 0x7F; + unsigned Reg = fieldFromInstruction(Insn, 7, 3); + + Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); + + Inst.addOperand(MCOperand::createReg(Reg)); + Inst.addOperand(MCOperand::createReg(Mips::GP)); + Inst.addOperand(MCOperand::createImm(Offset << 2)); + + return MCDisassembler::Success; +} + +static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<4>(Insn & 0xf); + + if (DecodeRegListOperand16(Inst, Insn, Address, Decoder) + == MCDisassembler::Fail) + return MCDisassembler::Fail; + + Inst.addOperand(MCOperand::createReg(Mips::SP)); + Inst.addOperand(MCOperand::createImm(Offset << 2)); + + return MCDisassembler::Success; +} + +static DecodeStatus DecodeMemMMImm9(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<9>(Insn & 0x1ff); + 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 DecodeMemMMImm12(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1038,12 +1377,26 @@ static DecodeStatus DecodeMemMMImm12(MCInst &Inst, Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); Base = getReg(Decoder, Mips::GPR32RegClassID, Base); - if (Inst.getOpcode() == Mips::SC_MM) - Inst.addOperand(MCOperand::CreateReg(Reg)); + switch (Inst.getOpcode()) { + case Mips::SWM32_MM: + case Mips::LWM32_MM: + if (DecodeRegListOperand(Inst, Insn, Address, Decoder) + == MCDisassembler::Fail) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); + break; + case Mips::SC_MM: + Inst.addOperand(MCOperand::createReg(Reg)); + // fallthrough + default: + Inst.addOperand(MCOperand::createReg(Reg)); + if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) + Inst.addOperand(MCOperand::createReg(Reg+1)); - Inst.addOperand(MCOperand::CreateReg(Reg)); - Inst.addOperand(MCOperand::CreateReg(Base)); - Inst.addOperand(MCOperand::CreateImm(Offset)); + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); + } return MCDisassembler::Success; } @@ -1059,9 +1412,9 @@ static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 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)); + Inst.addOperand(MCOperand::createReg(Reg)); + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); return MCDisassembler::Success; } @@ -1077,9 +1430,9 @@ static DecodeStatus DecodeFMem(MCInst &Inst, Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); Base = getReg(Decoder, Mips::GPR32RegClassID, Base); - Inst.addOperand(MCOperand::CreateReg(Reg)); - Inst.addOperand(MCOperand::CreateReg(Base)); - Inst.addOperand(MCOperand::CreateImm(Offset)); + Inst.addOperand(MCOperand::createReg(Reg)); + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); return MCDisassembler::Success; } @@ -1095,9 +1448,9 @@ static DecodeStatus DecodeFMem2(MCInst &Inst, Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); Base = getReg(Decoder, Mips::GPR32RegClassID, Base); - Inst.addOperand(MCOperand::CreateReg(Reg)); - Inst.addOperand(MCOperand::CreateReg(Base)); - Inst.addOperand(MCOperand::CreateImm(Offset)); + Inst.addOperand(MCOperand::createReg(Reg)); + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); return MCDisassembler::Success; } @@ -1113,13 +1466,30 @@ static DecodeStatus DecodeFMem3(MCInst &Inst, Reg = getReg(Decoder, Mips::COP3RegClassID, Reg); Base = getReg(Decoder, Mips::GPR32RegClassID, Base); - Inst.addOperand(MCOperand::CreateReg(Reg)); - Inst.addOperand(MCOperand::CreateReg(Base)); - Inst.addOperand(MCOperand::CreateImm(Offset)); + Inst.addOperand(MCOperand::createReg(Reg)); + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); return MCDisassembler::Success; } +static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<11>(Insn & 0x07ff); + unsigned Reg = fieldFromInstruction(Insn, 16, 5); + unsigned Base = fieldFromInstruction(Insn, 11, 5); + + Reg = getReg(Decoder, Mips::COP2RegClassID, 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 DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1132,12 +1502,12 @@ static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, Base = getReg(Decoder, Mips::GPR32RegClassID, Base); if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){ - Inst.addOperand(MCOperand::CreateReg(Rt)); + Inst.addOperand(MCOperand::createReg(Rt)); } - Inst.addOperand(MCOperand::CreateReg(Rt)); - Inst.addOperand(MCOperand::CreateReg(Base)); - Inst.addOperand(MCOperand::CreateImm(Offset)); + Inst.addOperand(MCOperand::createReg(Rt)); + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); return MCDisassembler::Success; } @@ -1149,7 +1519,7 @@ static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, // Currently only hardware register 29 is supported. if (RegNo != 29) return MCDisassembler::Fail; - Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); + Inst.addOperand(MCOperand::createReg(Mips::HWR29)); return MCDisassembler::Success; } @@ -1162,7 +1532,7 @@ static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, ; unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -1174,7 +1544,7 @@ static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -1186,7 +1556,7 @@ static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -1198,7 +1568,7 @@ static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -1210,7 +1580,7 @@ static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -1222,7 +1592,7 @@ static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -1234,7 +1604,7 @@ static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -1246,7 +1616,7 @@ static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -1258,7 +1628,19 @@ static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + + unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -1270,7 +1652,7 @@ static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, return MCDisassembler::Fail; unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo); - Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -1279,7 +1661,7 @@ static DecodeStatus DecodeBranchTarget(MCInst &Inst, uint64_t Address, const void *Decoder) { int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4; - Inst.addOperand(MCOperand::CreateImm(BranchOffset)); + Inst.addOperand(MCOperand::createImm(BranchOffset)); return MCDisassembler::Success; } @@ -1289,7 +1671,7 @@ static DecodeStatus DecodeJumpTarget(MCInst &Inst, const void *Decoder) { unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; - Inst.addOperand(MCOperand::CreateImm(JumpOffset)); + Inst.addOperand(MCOperand::createImm(JumpOffset)); return MCDisassembler::Success; } @@ -1299,7 +1681,7 @@ static DecodeStatus DecodeBranchTarget21(MCInst &Inst, const void *Decoder) { int32_t BranchOffset = SignExtend32<21>(Offset) * 4; - Inst.addOperand(MCOperand::CreateImm(BranchOffset)); + Inst.addOperand(MCOperand::createImm(BranchOffset)); return MCDisassembler::Success; } @@ -1309,7 +1691,25 @@ static DecodeStatus DecodeBranchTarget26(MCInst &Inst, const void *Decoder) { int32_t BranchOffset = SignExtend32<26>(Offset) * 4; - Inst.addOperand(MCOperand::CreateImm(BranchOffset)); + Inst.addOperand(MCOperand::createImm(BranchOffset)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder) { + int32_t BranchOffset = SignExtend32<7>(Offset) << 1; + Inst.addOperand(MCOperand::createImm(BranchOffset)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder) { + int32_t BranchOffset = SignExtend32<10>(Offset) << 1; + Inst.addOperand(MCOperand::createImm(BranchOffset)); return MCDisassembler::Success; } @@ -1318,7 +1718,7 @@ static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, uint64_t Address, const void *Decoder) { int32_t BranchOffset = SignExtend32<16>(Offset) * 2; - Inst.addOperand(MCOperand::CreateImm(BranchOffset)); + Inst.addOperand(MCOperand::createImm(BranchOffset)); return MCDisassembler::Success; } @@ -1327,7 +1727,47 @@ static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, uint64_t Address, const void *Decoder) { unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1; - Inst.addOperand(MCOperand::CreateImm(JumpOffset)); + Inst.addOperand(MCOperand::createImm(JumpOffset)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, + unsigned Value, + uint64_t Address, + const void *Decoder) { + if (Value == 0) + Inst.addOperand(MCOperand::createImm(1)); + else if (Value == 0x7) + Inst.addOperand(MCOperand::createImm(-1)); + else + Inst.addOperand(MCOperand::createImm(Value << 2)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, + unsigned Value, + uint64_t Address, + const void *Decoder) { + Inst.addOperand(MCOperand::createImm(Value << 2)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeLiSimm7(MCInst &Inst, + unsigned Value, + uint64_t Address, + const void *Decoder) { + if (Value == 0x7F) + Inst.addOperand(MCOperand::createImm(-1)); + else + Inst.addOperand(MCOperand::createImm(Value)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeSimm4(MCInst &Inst, + unsigned Value, + uint64_t Address, + const void *Decoder) { + Inst.addOperand(MCOperand::createImm(SignExtend32<4>(Value))); return MCDisassembler::Success; } @@ -1335,7 +1775,7 @@ static DecodeStatus DecodeSimm16(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { - Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); + Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Insn))); return MCDisassembler::Success; } @@ -1344,7 +1784,7 @@ static DecodeStatus DecodeLSAImm(MCInst &Inst, uint64_t Address, const void *Decoder) { // We add one to the immediate field as it was encoded as 'imm - 1'. - Inst.addOperand(MCOperand::CreateImm(Insn + 1)); + Inst.addOperand(MCOperand::createImm(Insn + 1)); return MCDisassembler::Success; } @@ -1355,7 +1795,7 @@ static DecodeStatus DecodeInsSize(MCInst &Inst, // First we need to grab the pos(lsb) from MCInst. int Pos = Inst.getOperand(2).getImm(); int Size = (int) Insn - Pos + 1; - Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); + Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size))); return MCDisassembler::Success; } @@ -1364,18 +1804,137 @@ static DecodeStatus DecodeExtSize(MCInst &Inst, uint64_t Address, const void *Decoder) { int Size = (int) Insn + 1; - Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); + Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size))); return MCDisassembler::Success; } static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { - Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) * 4)); + Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4)); return MCDisassembler::Success; } static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { - Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) * 8)); + Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + int32_t DecodedValue; + switch (Insn) { + case 0: DecodedValue = 256; break; + case 1: DecodedValue = 257; break; + case 510: DecodedValue = -258; break; + case 511: DecodedValue = -257; break; + default: DecodedValue = SignExtend32<9>(Insn); break; + } + Inst.addOperand(MCOperand::createImm(DecodedValue * 4)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + // Insn must be >= 0, since it is unsigned that condition is always true. + assert(Insn < 16); + int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, + 255, 32768, 65535}; + Inst.addOperand(MCOperand::createImm(DecodedValues[Insn])); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + Inst.addOperand(MCOperand::createImm(Insn << 2)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeRegListOperand(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5, + Mips::S6, Mips::FP}; + unsigned RegNum; + + unsigned RegLst = fieldFromInstruction(Insn, 21, 5); + // Empty register lists are not allowed. + if (RegLst == 0) + return MCDisassembler::Fail; + + RegNum = RegLst & 0xf; + for (unsigned i = 0; i < RegNum; i++) + Inst.addOperand(MCOperand::createReg(Regs[i])); + + if (RegLst & 0x10) + Inst.addOperand(MCOperand::createReg(Mips::RA)); + + return MCDisassembler::Success; +} + +static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, + uint64_t Address, + const void *Decoder) { + unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3}; + unsigned RegLst = fieldFromInstruction(Insn, 4, 2); + unsigned RegNum = RegLst & 0x3; + + for (unsigned i = 0; i <= RegNum; i++) + Inst.addOperand(MCOperand::createReg(Regs[i])); + + Inst.addOperand(MCOperand::createReg(Mips::RA)); + + return MCDisassembler::Success; +} + +static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + + unsigned RegPair = fieldFromInstruction(Insn, 7, 3); + + switch (RegPair) { + default: + return MCDisassembler::Fail; + case 0: + Inst.addOperand(MCOperand::createReg(Mips::A1)); + Inst.addOperand(MCOperand::createReg(Mips::A2)); + break; + case 1: + Inst.addOperand(MCOperand::createReg(Mips::A1)); + Inst.addOperand(MCOperand::createReg(Mips::A3)); + break; + case 2: + Inst.addOperand(MCOperand::createReg(Mips::A2)); + Inst.addOperand(MCOperand::createReg(Mips::A3)); + break; + case 3: + Inst.addOperand(MCOperand::createReg(Mips::A0)); + Inst.addOperand(MCOperand::createReg(Mips::S5)); + break; + case 4: + Inst.addOperand(MCOperand::createReg(Mips::A0)); + Inst.addOperand(MCOperand::createReg(Mips::S6)); + break; + case 5: + Inst.addOperand(MCOperand::createReg(Mips::A0)); + Inst.addOperand(MCOperand::createReg(Mips::A1)); + break; + case 6: + Inst.addOperand(MCOperand::createReg(Mips::A0)); + Inst.addOperand(MCOperand::createReg(Mips::A2)); + break; + case 7: + Inst.addOperand(MCOperand::createReg(Mips::A0)); + Inst.addOperand(MCOperand::createReg(Mips::A3)); + break; + } + + return MCDisassembler::Success; +} + +static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2))); return MCDisassembler::Success; }