X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FDisassembler%2FMipsDisassembler.cpp;h=c8a5195e8e6863686722f4daf6c50d4acee3ac5a;hb=3c537720006f52b105357d29d17c05af79b6c72b;hp=d29347d6213c77a9ac44ca1897c3b1e6f92866b3;hpb=78f6aad800eb677a3748531a862395a162cc3d82;p=oota-llvm.git diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index d29347d6213..c8a5195e8e6 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -30,26 +30,26 @@ typedef MCDisassembler::DecodeStatus DecodeStatus; namespace { -/// A disasembler class for Mips. +/// A disassembler class for Mips. class MipsDisassemblerBase : public MCDisassembler { public: MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian) : MCDisassembler(STI, Ctx), - IsN64(STI.getFeatureBits() & Mips::FeatureN64), + IsGP64Bit(STI.getFeatureBits() & Mips::FeatureGP64Bit), IsBigEndian(IsBigEndian) {} virtual ~MipsDisassemblerBase() {} - bool isN64() const { return IsN64; } + bool isGP64Bit() const { return IsGP64Bit; } private: - bool IsN64; + bool IsGP64Bit; protected: bool IsBigEndian; }; -/// A disasembler class for Mips32. +/// A disassembler class for Mips32. class MipsDisassembler : public MipsDisassemblerBase { bool IsMicroMips; public: @@ -77,7 +77,7 @@ public: raw_ostream &CStream) const override; }; -/// A disasembler class for Mips64. +/// A disassembler class for Mips64. class Mips64Disassembler : public MipsDisassemblerBase { public: Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx, @@ -114,6 +114,11 @@ static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, 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, @@ -228,6 +233,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, @@ -252,6 +271,16 @@ 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 DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -265,6 +294,21 @@ static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 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 DecodeMemMMImm12(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -287,6 +331,10 @@ 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, @@ -349,6 +397,9 @@ static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 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 @@ -393,6 +444,10 @@ 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; @@ -959,6 +1014,17 @@ static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, 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, unsigned RegNo, uint64_t Address, @@ -974,7 +1040,7 @@ static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { - if (static_cast(Decoder)->isN64()) + if (static_cast(Decoder)->isGP64Bit()) return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); @@ -1084,6 +1150,40 @@ static DecodeStatus DecodeCacheOp(MCInst &Inst, 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 DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1197,6 +1297,54 @@ static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 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 DecodeMemMMImm12(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1304,6 +1452,23 @@ static DecodeStatus DecodeFMem3(MCInst &Inst, 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, @@ -1497,6 +1662,24 @@ static DecodeStatus DecodeBranchTarget26(MCInst &Inst, 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; +} + static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, unsigned Offset, uint64_t Address, @@ -1614,7 +1797,7 @@ static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, case 511: DecodedValue = -257; break; default: DecodedValue = SignExtend32<9>(Insn); break; } - Inst.addOperand(MCOperand::CreateImm(DecodedValue << 2)); + Inst.addOperand(MCOperand::CreateImm(DecodedValue * 4)); return MCDisassembler::Success; } @@ -1661,18 +1844,64 @@ static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3}; - unsigned RegNum; - unsigned RegLst = fieldFromInstruction(Insn, 4, 2); - // Empty register lists are not allowed. - if (RegLst == 0) - return MCDisassembler::Fail; + unsigned RegNum = RegLst & 0x3; - RegNum = RegLst & 0x3; - for (unsigned i = 0; i < RegNum - 1; i++) + 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<23>(Insn) << 2)); + return MCDisassembler::Success; +}