diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
commit | 0b57cec536236d46e3dba9bd041533462f33dbb7 (patch) | |
tree | 56229dbdbbf76d18580f72f789003db17246c8d9 /contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp | |
parent | 718ef55ec7785aae63f98f8ca05dc07ed399c16d (diff) |
Notes
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 2621 |
1 files changed, 0 insertions, 2621 deletions
diff --git a/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp deleted file mode 100644 index 9fdf4e390e10..000000000000 --- a/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ /dev/null @@ -1,2621 +0,0 @@ -//===- MipsDisassembler.cpp - Disassembler for Mips -----------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file is part of the Mips Disassembler. -// -//===----------------------------------------------------------------------===// - -#include "MCTargetDesc/MipsMCTargetDesc.h" -#include "Mips.h" -#include "TargetInfo/MipsTargetInfo.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCDisassembler/MCDisassembler.h" -#include "llvm/MC/MCFixedLenDisassembler.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCRegisterInfo.h" -#include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/raw_ostream.h" -#include <cassert> -#include <cstdint> - -using namespace llvm; - -#define DEBUG_TYPE "mips-disassembler" - -using DecodeStatus = MCDisassembler::DecodeStatus; - -namespace { - -class MipsDisassembler : public MCDisassembler { - bool IsMicroMips; - bool IsBigEndian; - -public: - MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian) - : MCDisassembler(STI, Ctx), - IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]), - IsBigEndian(IsBigEndian) {} - - bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; } - bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; } - bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; } - - bool hasMips32r6() const { - return STI.getFeatureBits()[Mips::FeatureMips32r6]; - } - - bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; } - - bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; } - - bool isPTR64() const { return STI.getFeatureBits()[Mips::FeaturePTR64Bit]; } - - bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; } - - bool hasCnMipsP() const { return STI.getFeatureBits()[Mips::FeatureCnMipsP]; } - - bool hasCOP3() const { - // Only present in MIPS-I and MIPS-II - return !hasMips32() && !hasMips3(); - } - - DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, - ArrayRef<uint8_t> Bytes, uint64_t Address, - raw_ostream &VStream, - raw_ostream &CStream) const override; -}; - -} // end anonymous namespace - -// Forward declare these because the autogenerated code will reference them. -// Definitions are further down. -static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, - unsigned RegNo, - 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, - const void *Decoder); - -static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, - unsigned RegNo, - 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, - const void *Decoder); - -static DecodeStatus DecodeBranchTarget(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeJumpTarget(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeBranchTarget21(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeBranchTarget26(MCInst &Inst, - unsigned Offset, - 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, - unsigned Offset, - uint64_t Address, - const void *Decoder); - -// DecodeBranchTarget26MM - Decode microMIPS branch offset, which is -// shifted left by 1 bit. -static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder); - -// DecodeJumpTargetMM - Decode microMIPS jump target, which is -// shifted left by 1 bit. -static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeMem(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeMemEVA(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeLoadByte15(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeCacheeOp_CacheOpR6(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 DecodePrefeOpMM(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 DecodeSyncI_MM(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeSynciR6(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, - 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); - -static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address, - const void *Decoder); - -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 DecodeFMemCop2MMR6(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 DecodeLi16Imm(MCInst &Inst, - unsigned Value, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, - unsigned Value, - uint64_t Address, - const void *Decoder); - -template <unsigned Bits, int Offset, int Scale> -static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, - uint64_t Address, - const void *Decoder); - -template <unsigned Bits, int Offset> -static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value, - uint64_t Address, - const void *Decoder) { - return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address, - Decoder); -} - -template <unsigned Bits, int Offset = 0, int ScaleBy = 1> -static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeInsSize(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, - uint64_t Address, const void *Decoder); - -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 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 <typename InsnType> -static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus -DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus -DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus -DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus -DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus -DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus -DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus -DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus -DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus -DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus -DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus -DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus -DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address, - const void *Decoder); - -template <typename InsnType> -static DecodeStatus DecodeCRC(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 RegPair, - uint64_t Address, - const void *Decoder); - -static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn, - uint64_t Address, const void *Decoder); - -static MCDisassembler *createMipsDisassembler( - const Target &T, - const MCSubtargetInfo &STI, - MCContext &Ctx) { - return new MipsDisassembler(STI, Ctx, true); -} - -static MCDisassembler *createMipselDisassembler( - const Target &T, - const MCSubtargetInfo &STI, - MCContext &Ctx) { - return new MipsDisassembler(STI, Ctx, false); -} - -extern "C" void LLVMInitializeMipsDisassembler() { - // Register the disassembler. - TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(), - createMipsDisassembler); - TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(), - createMipselDisassembler); - TargetRegistry::RegisterMCDisassembler(getTheMips64Target(), - createMipsDisassembler); - TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(), - createMipselDisassembler); -} - -#include "MipsGenDisassemblerTables.inc" - -static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { - const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D); - const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo(); - return *(RegInfo->getRegClass(RC).begin() + RegNo); -} - -template <typename InsnType> -static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder) { - using DecodeFN = DecodeStatus (*)(MCInst &, unsigned, uint64_t, const void *); - - // The size of the n field depends on the element size - // The register class also depends on this. - InsnType tmp = fieldFromInstruction(insn, 17, 5); - unsigned NSize = 0; - DecodeFN RegDecoder = nullptr; - if ((tmp & 0x18) == 0x00) { // INSVE_B - NSize = 4; - RegDecoder = DecodeMSA128BRegisterClass; - } else if ((tmp & 0x1c) == 0x10) { // INSVE_H - NSize = 3; - RegDecoder = DecodeMSA128HRegisterClass; - } else if ((tmp & 0x1e) == 0x18) { // INSVE_W - NSize = 2; - RegDecoder = DecodeMSA128WRegisterClass; - } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D - NSize = 1; - RegDecoder = DecodeMSA128DRegisterClass; - } else - llvm_unreachable("Invalid encoding"); - - assert(NSize != 0 && RegDecoder != nullptr); - - // $wd - tmp = fieldFromInstruction(insn, 6, 5); - if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) - return MCDisassembler::Fail; - // $wd_in - if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) - return MCDisassembler::Fail; - // $n - tmp = fieldFromInstruction(insn, 16, NSize); - 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)); - - return MCDisassembler::Success; -} - -template <typename InsnType> -static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder) { - InsnType Rs = fieldFromInstruction(insn, 16, 5); - InsnType Imm = fieldFromInstruction(insn, 0, 16); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, - Rs))); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, - Rs))); - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} - -template <typename InsnType> -static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder) { - InsnType Rs = fieldFromInstruction(insn, 21, 5); - InsnType Imm = fieldFromInstruction(insn, 0, 16); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, - Rs))); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, - Rs))); - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} - -template <typename InsnType> -static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, - uint64_t Address, - const void *Decoder) { - // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled - // (otherwise we would have matched the ADDI instruction from the earlier - // ISA's instead). - // - // We have: - // 0b001000 sssss ttttt iiiiiiiiiiiiiiii - // BOVC if rs >= rt - // BEQZALC if rs == 0 && rt != 0 - // BEQC if rs < rt && rs != 0 - - InsnType Rs = fieldFromInstruction(insn, 21, 5); - InsnType Rt = fieldFromInstruction(insn, 16, 5); - int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; - bool HasRs = false; - - if (Rs >= Rt) { - MI.setOpcode(Mips::BOVC); - HasRs = true; - } else if (Rs != 0 && Rs < Rt) { - MI.setOpcode(Mips::BEQC); - HasRs = true; - } else - MI.setOpcode(Mips::BEQZALC); - - if (HasRs) - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rs))); - - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} - -template <typename InsnType> -static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, - uint64_t Address, - const void *Decoder) { - InsnType Rt = fieldFromInstruction(insn, 21, 5); - InsnType Rs = fieldFromInstruction(insn, 16, 5); - int64_t Imm = 0; - - if (Rs >= Rt) { - MI.setOpcode(Mips::BOVC_MMR6); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rs))); - Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; - } else if (Rs != 0 && Rs < Rt) { - MI.setOpcode(Mips::BEQC_MMR6); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rs))); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; - } else { - MI.setOpcode(Mips::BEQZALC_MMR6); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; - } - - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} - -template <typename InsnType> -static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, - uint64_t Address, - const void *Decoder) { - // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled - // (otherwise we would have matched the ADDI instruction from the earlier - // ISA's instead). - // - // We have: - // 0b011000 sssss ttttt iiiiiiiiiiiiiiii - // BNVC if rs >= rt - // BNEZALC if rs == 0 && rt != 0 - // BNEC if rs < rt && rs != 0 - - InsnType Rs = fieldFromInstruction(insn, 21, 5); - InsnType Rt = fieldFromInstruction(insn, 16, 5); - int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; - bool HasRs = false; - - if (Rs >= Rt) { - MI.setOpcode(Mips::BNVC); - HasRs = true; - } else if (Rs != 0 && Rs < Rt) { - MI.setOpcode(Mips::BNEC); - HasRs = true; - } else - MI.setOpcode(Mips::BNEZALC); - - if (HasRs) - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rs))); - - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} - -template <typename InsnType> -static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, - uint64_t Address, - const void *Decoder) { - InsnType Rt = fieldFromInstruction(insn, 21, 5); - InsnType Rs = fieldFromInstruction(insn, 16, 5); - int64_t Imm = 0; - - if (Rs >= Rt) { - MI.setOpcode(Mips::BNVC_MMR6); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rs))); - Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; - } else if (Rs != 0 && Rs < Rt) { - MI.setOpcode(Mips::BNEC_MMR6); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rs))); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; - } else { - MI.setOpcode(Mips::BNEZALC_MMR6); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; - } - - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} - -template <typename InsnType> -static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, - uint64_t Address, - const void *Decoder) { - // We have: - // 0b110101 ttttt sssss iiiiiiiiiiiiiiii - // Invalid if rt == 0 - // BGTZC_MMR6 if rs == 0 && rt != 0 - // BLTZC_MMR6 if rs == rt && rt != 0 - // BLTC_MMR6 if rs != rt && rs != 0 && rt != 0 - - InsnType Rt = fieldFromInstruction(insn, 21, 5); - InsnType Rs = fieldFromInstruction(insn, 16, 5); - int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; - bool HasRs = false; - - if (Rt == 0) - return MCDisassembler::Fail; - else if (Rs == 0) - MI.setOpcode(Mips::BGTZC_MMR6); - else if (Rs == Rt) - MI.setOpcode(Mips::BLTZC_MMR6); - else { - MI.setOpcode(Mips::BLTC_MMR6); - HasRs = true; - } - - if (HasRs) - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rs))); - - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} - -template <typename InsnType> -static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, - uint64_t Address, - const void *Decoder) { - // We have: - // 0b111101 ttttt sssss iiiiiiiiiiiiiiii - // Invalid if rt == 0 - // BLEZC_MMR6 if rs == 0 && rt != 0 - // BGEZC_MMR6 if rs == rt && rt != 0 - // BGEC_MMR6 if rs != rt && rs != 0 && rt != 0 - - InsnType Rt = fieldFromInstruction(insn, 21, 5); - InsnType Rs = fieldFromInstruction(insn, 16, 5); - int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; - bool HasRs = false; - - if (Rt == 0) - return MCDisassembler::Fail; - else if (Rs == 0) - MI.setOpcode(Mips::BLEZC_MMR6); - else if (Rs == Rt) - MI.setOpcode(Mips::BGEZC_MMR6); - else { - HasRs = true; - MI.setOpcode(Mips::BGEC_MMR6); - } - - if (HasRs) - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rs))); - - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} - -template <typename InsnType> -static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, - uint64_t Address, - const void *Decoder) { - // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled - // (otherwise we would have matched the BLEZL instruction from the earlier - // ISA's instead). - // - // We have: - // 0b010110 sssss ttttt iiiiiiiiiiiiiiii - // Invalid if rs == 0 - // BLEZC if rs == 0 && rt != 0 - // BGEZC if rs == rt && rt != 0 - // BGEC if rs != rt && rs != 0 && rt != 0 - - InsnType Rs = fieldFromInstruction(insn, 21, 5); - InsnType Rt = fieldFromInstruction(insn, 16, 5); - int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; - bool HasRs = false; - - if (Rt == 0) - return MCDisassembler::Fail; - else if (Rs == 0) - MI.setOpcode(Mips::BLEZC); - else if (Rs == Rt) - MI.setOpcode(Mips::BGEZC); - else { - HasRs = true; - MI.setOpcode(Mips::BGEC); - } - - if (HasRs) - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rs))); - - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} - -template <typename InsnType> -static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, - uint64_t Address, - const void *Decoder) { - // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled - // (otherwise we would have matched the BGTZL instruction from the earlier - // ISA's instead). - // - // We have: - // 0b010111 sssss ttttt iiiiiiiiiiiiiiii - // Invalid if rs == 0 - // BGTZC if rs == 0 && rt != 0 - // BLTZC if rs == rt && rt != 0 - // BLTC if rs != rt && rs != 0 && rt != 0 - - bool HasRs = false; - - InsnType Rs = fieldFromInstruction(insn, 21, 5); - InsnType Rt = fieldFromInstruction(insn, 16, 5); - int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; - - if (Rt == 0) - return MCDisassembler::Fail; - else if (Rs == 0) - MI.setOpcode(Mips::BGTZC); - else if (Rs == Rt) - MI.setOpcode(Mips::BLTZC); - else { - MI.setOpcode(Mips::BLTC); - HasRs = true; - } - - if (HasRs) - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rs))); - - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} - -template <typename InsnType> -static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, - uint64_t Address, - const void *Decoder) { - // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled - // (otherwise we would have matched the BGTZ instruction from the earlier - // ISA's instead). - // - // We have: - // 0b000111 sssss ttttt iiiiiiiiiiiiiiii - // BGTZ if rt == 0 - // BGTZALC if rs == 0 && rt != 0 - // BLTZALC if rs != 0 && rs == rt - // BLTUC if rs != 0 && rs != rt - - InsnType Rs = fieldFromInstruction(insn, 21, 5); - InsnType Rt = fieldFromInstruction(insn, 16, 5); - int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; - bool HasRs = false; - bool HasRt = false; - - if (Rt == 0) { - MI.setOpcode(Mips::BGTZ); - HasRs = true; - } else if (Rs == 0) { - MI.setOpcode(Mips::BGTZALC); - HasRt = true; - } else if (Rs == Rt) { - MI.setOpcode(Mips::BLTZALC); - HasRs = true; - } else { - MI.setOpcode(Mips::BLTUC); - HasRs = true; - HasRt = true; - } - - if (HasRs) - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rs))); - - if (HasRt) - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} - -template <typename InsnType> -static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn, - uint64_t Address, - const void *Decoder) { - // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled - // (otherwise we would have matched the BLEZL instruction from the earlier - // ISA's instead). - // - // We have: - // 0b000110 sssss ttttt iiiiiiiiiiiiiiii - // Invalid if rs == 0 - // BLEZALC if rs == 0 && rt != 0 - // BGEZALC if rs == rt && rt != 0 - // BGEUC if rs != rt && rs != 0 && rt != 0 - - InsnType Rs = fieldFromInstruction(insn, 21, 5); - InsnType Rt = fieldFromInstruction(insn, 16, 5); - int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; - bool HasRs = false; - - if (Rt == 0) - return MCDisassembler::Fail; - else if (Rs == 0) - MI.setOpcode(Mips::BLEZALC); - else if (Rs == Rt) - MI.setOpcode(Mips::BGEZALC); - else { - HasRs = true; - MI.setOpcode(Mips::BGEUC); - } - - if (HasRs) - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rs))); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} - -// Override the generated disassembler to produce DEXT all the time. This is -// for feature / behaviour parity with binutils. -template <typename InsnType> -static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address, - const void *Decoder) { - unsigned Msbd = fieldFromInstruction(Insn, 11, 5); - unsigned Lsb = fieldFromInstruction(Insn, 6, 5); - unsigned Size = 0; - unsigned Pos = 0; - - switch (MI.getOpcode()) { - case Mips::DEXT: - Pos = Lsb; - Size = Msbd + 1; - break; - case Mips::DEXTM: - Pos = Lsb; - Size = Msbd + 1 + 32; - break; - case Mips::DEXTU: - Pos = Lsb + 32; - Size = Msbd + 1; - break; - default: - llvm_unreachable("Unknown DEXT instruction!"); - } - - MI.setOpcode(Mips::DEXT); - - InsnType Rs = fieldFromInstruction(Insn, 21, 5); - InsnType Rt = fieldFromInstruction(Insn, 16, 5); - - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt))); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs))); - MI.addOperand(MCOperand::createImm(Pos)); - MI.addOperand(MCOperand::createImm(Size)); - - return MCDisassembler::Success; -} - -// Override the generated disassembler to produce DINS all the time. This is -// for feature / behaviour parity with binutils. -template <typename InsnType> -static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address, - const void *Decoder) { - unsigned Msbd = fieldFromInstruction(Insn, 11, 5); - unsigned Lsb = fieldFromInstruction(Insn, 6, 5); - unsigned Size = 0; - unsigned Pos = 0; - - switch (MI.getOpcode()) { - case Mips::DINS: - Pos = Lsb; - Size = Msbd + 1 - Pos; - break; - case Mips::DINSM: - Pos = Lsb; - Size = Msbd + 33 - Pos; - break; - case Mips::DINSU: - Pos = Lsb + 32; - // mbsd = pos + size - 33 - // mbsd - pos + 33 = size - Size = Msbd + 33 - Pos; - break; - default: - llvm_unreachable("Unknown DINS instruction!"); - } - - InsnType Rs = fieldFromInstruction(Insn, 21, 5); - InsnType Rt = fieldFromInstruction(Insn, 16, 5); - - MI.setOpcode(Mips::DINS); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt))); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs))); - MI.addOperand(MCOperand::createImm(Pos)); - MI.addOperand(MCOperand::createImm(Size)); - - return MCDisassembler::Success; -} - -// Auto-generated decoder wouldn't add the third operand for CRC32*. -template <typename InsnType> -static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address, - const void *Decoder) { - InsnType Rs = fieldFromInstruction(Insn, 21, 5); - InsnType Rt = fieldFromInstruction(Insn, 16, 5); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rs))); - MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, - Rt))); - return MCDisassembler::Success; -} - -/// Read two bytes from the ArrayRef and return 16 bit halfword sorted -/// according to the given endianness. -static DecodeStatus readInstruction16(ArrayRef<uint8_t> 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 endianness. -static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, - uint64_t &Size, uint32_t &Insn, - bool IsBigEndian, bool IsMicroMips) { - // We want to read exactly 4 Bytes of data. - 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 { - 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; -} - -DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, - ArrayRef<uint8_t> Bytes, - uint64_t Address, - raw_ostream &VStream, - raw_ostream &CStream) const { - uint32_t Insn; - DecodeStatus Result; - Size = 0; - - if (IsMicroMips) { - Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); - if (Result == MCDisassembler::Fail) - return MCDisassembler::Fail; - - if (hasMips32r6()) { - LLVM_DEBUG( - dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n"); - // Calling the auto-generated decoder function for microMIPS32R6 - // 16-bit instructions. - Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn, - Address, this, STI); - if (Result != MCDisassembler::Fail) { - Size = 2; - return Result; - } - } - - LLVM_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()) { - LLVM_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; - } - } - - LLVM_DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); - // Calling the auto-generated decoder function. - Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, - this, STI); - if (Result != MCDisassembler::Fail) { - Size = 4; - return Result; - } - - if (isFP64()) { - LLVM_DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n"); - Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn, - Address, this, STI); - if (Result != MCDisassembler::Fail) { - Size = 4; - return Result; - } - } - - // This is an invalid instruction. Claim that the Size is 2 bytes. Since - // microMIPS instructions have a minimum alignment of 2, the next 2 bytes - // could form a valid instruction. The two bytes we rejected as an - // instruction could have actually beeen an inline constant pool that is - // unconditionally branched over. - Size = 2; - return MCDisassembler::Fail; - } - - // Attempt to read the instruction so that we can attempt to decode it. If - // the buffer is not 4 bytes long, let the higher level logic figure out - // what to do with a size of zero and MCDisassembler::Fail. - Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); - if (Result == MCDisassembler::Fail) - return MCDisassembler::Fail; - - // The only instruction size for standard encoded MIPS. - Size = 4; - - if (hasCOP3()) { - LLVM_DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n"); - Result = - decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI); - if (Result != MCDisassembler::Fail) - return Result; - } - - if (hasMips32r6() && isGP64()) { - LLVM_DEBUG( - dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n"); - Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn, - Address, this, STI); - if (Result != MCDisassembler::Fail) - return Result; - } - - if (hasMips32r6() && isPTR64()) { - LLVM_DEBUG( - dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n"); - Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn, - Address, this, STI); - if (Result != MCDisassembler::Fail) - return Result; - } - - if (hasMips32r6()) { - LLVM_DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n"); - Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn, - Address, this, STI); - if (Result != MCDisassembler::Fail) - return Result; - } - - if (hasMips2() && isPTR64()) { - LLVM_DEBUG( - dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n"); - Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn, - Address, this, STI); - if (Result != MCDisassembler::Fail) - return Result; - } - - if (hasCnMips()) { - LLVM_DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n"); - Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn, - Address, this, STI); - if (Result != MCDisassembler::Fail) - return Result; - } - - if (hasCnMipsP()) { - LLVM_DEBUG(dbgs() << "Trying CnMipsP table (32-bit opcodes):\n"); - Result = decodeInstruction(DecoderTableCnMipsP32, Instr, Insn, - Address, this, STI); - if (Result != MCDisassembler::Fail) - return Result; - } - - if (isGP64()) { - LLVM_DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n"); - Result = decodeInstruction(DecoderTableMips6432, Instr, Insn, - Address, this, STI); - if (Result != MCDisassembler::Fail) - return Result; - } - - if (isFP64()) { - LLVM_DEBUG( - dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n"); - Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn, - Address, this, STI); - if (Result != MCDisassembler::Fail) - return Result; - } - - LLVM_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) - return Result; - - return MCDisassembler::Fail; -} - -static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - return MCDisassembler::Fail; -} - -static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 31) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - 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, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 31) - return MCDisassembler::Fail; - unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (static_cast<const MipsDisassembler *>(Decoder)->isGP64()) - return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); - - return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); -} - -static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); -} - -static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 31) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 31) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 31) - return MCDisassembler::Fail; - unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 7) - return MCDisassembler::Fail; - unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 31) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeMem(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - int Offset = SignExtend32<16>(Insn & 0xffff); - unsigned Reg = fieldFromInstruction(Insn, 16, 5); - unsigned Base = fieldFromInstruction(Insn, 21, 5); - - Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); - Base = getReg(Decoder, Mips::GPR32RegClassID, Base); - - 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)); - - return MCDisassembler::Success; -} - -static DecodeStatus DecodeMemEVA(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - int Offset = SignExtend32<9>(Insn >> 7); - unsigned Reg = fieldFromInstruction(Insn, 16, 5); - unsigned Base = fieldFromInstruction(Insn, 21, 5); - - Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); - Base = getReg(Decoder, Mips::GPR32RegClassID, Base); - - if (Inst.getOpcode() == Mips::SCE) - Inst.addOperand(MCOperand::createReg(Reg)); - - Inst.addOperand(MCOperand::createReg(Reg)); - Inst.addOperand(MCOperand::createReg(Base)); - Inst.addOperand(MCOperand::createImm(Offset)); - - return MCDisassembler::Success; -} - -static DecodeStatus DecodeLoadByte15(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - int Offset = SignExtend32<16>(Insn & 0xffff); - unsigned Base = fieldFromInstruction(Insn, 16, 5); - unsigned Reg = fieldFromInstruction(Insn, 21, 5); - - Base = getReg(Decoder, Mips::GPR32RegClassID, Base); - Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); - - Inst.addOperand(MCOperand::createReg(Reg)); - Inst.addOperand(MCOperand::createReg(Base)); - Inst.addOperand(MCOperand::createImm(Offset)); - - return MCDisassembler::Success; -} - -static DecodeStatus DecodeCacheOp(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - int Offset = SignExtend32<16>(Insn & 0xffff); - 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 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 DecodePrefeOpMM(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - int Offset = SignExtend32<9>(Insn & 0x1ff); - 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 DecodeCacheeOp_CacheOpR6(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - int Offset = SignExtend32<9>(Insn >> 7); - 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, - 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; -} - -static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn, - uint64_t Address, const void *Decoder) { - int Offset = SignExtend32<16>(Insn & 0xffff); - unsigned Base = fieldFromInstruction(Insn, 16, 5); - - Base = getReg(Decoder, Mips::GPR32RegClassID, Base); - - Inst.addOperand(MCOperand::createReg(Base)); - Inst.addOperand(MCOperand::createImm(Offset)); - - return MCDisassembler::Success; -} - -static DecodeStatus DecodeSynciR6(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - int Immediate = SignExtend32<16>(Insn & 0xffff); - unsigned Base = fieldFromInstruction(Insn, 16, 5); - - Base = getReg(Decoder, Mips::GPR32RegClassID, Base); - - Inst.addOperand(MCOperand::createReg(Base)); - Inst.addOperand(MCOperand::createImm(Immediate)); - - return MCDisassembler::Success; -} - -static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, - uint64_t Address, const void *Decoder) { - int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10)); - unsigned Reg = fieldFromInstruction(Insn, 6, 5); - unsigned Base = fieldFromInstruction(Insn, 11, 5); - - Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg); - Base = getReg(Decoder, Mips::GPR32RegClassID, 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' - // data format. - // .b - 1 byte - // .h - 2 bytes - // .w - 4 bytes - // .d - 8 bytes - switch(Inst.getOpcode()) - { - default: - assert(false && "Unexpected instruction"); - return MCDisassembler::Fail; - break; - case Mips::LD_B: - case Mips::ST_B: - Inst.addOperand(MCOperand::createImm(Offset)); - break; - case Mips::LD_H: - case Mips::ST_H: - Inst.addOperand(MCOperand::createImm(Offset * 2)); - break; - case Mips::LD_W: - case Mips::ST_W: - Inst.addOperand(MCOperand::createImm(Offset * 4)); - break; - case Mips::LD_D: - case Mips::ST_D: - 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::SB16_MMR6: - case Mips::SH16_MM: - case Mips::SH16_MMR6: - case Mips::SW16_MM: - case Mips::SW16_MMR6: - 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: - case Mips::SB16_MMR6: - Inst.addOperand(MCOperand::createImm(Offset)); - break; - case Mips::LHU16_MM: - case Mips::SH16_MM: - case Mips::SH16_MMR6: - Inst.addOperand(MCOperand::createImm(Offset << 1)); - break; - case Mips::LW16_MM: - case Mips::SW16_MM: - case Mips::SW16_MMR6: - 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; - switch (Inst.getOpcode()) { - case Mips::LWM16_MMR6: - case Mips::SWM16_MMR6: - Offset = fieldFromInstruction(Insn, 4, 4); - break; - default: - Offset = SignExtend32<4>(Insn & 0xf); - break; - } - - 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); - - if (Inst.getOpcode() == Mips::SCE_MM || Inst.getOpcode() == Mips::SC_MMR6) - Inst.addOperand(MCOperand::createReg(Reg)); - - 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, - 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); - - 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)); - LLVM_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(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, - const void *Decoder) { - int Offset = SignExtend32<16>(Insn & 0xffff); - unsigned Reg = fieldFromInstruction(Insn, 16, 5); - unsigned Base = fieldFromInstruction(Insn, 21, 5); - - 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)); - - return MCDisassembler::Success; -} - -static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn, - uint64_t Address, const void *Decoder) { - // This function is the same as DecodeFMem but with the Reg and Base fields - // swapped according to microMIPS spec. - int Offset = SignExtend32<16>(Insn & 0xffff); - unsigned Base = fieldFromInstruction(Insn, 16, 5); - unsigned Reg = fieldFromInstruction(Insn, 21, 5); - - 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)); - - return MCDisassembler::Success; -} - -static DecodeStatus DecodeFMem2(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - int Offset = SignExtend32<16>(Insn & 0xffff); - unsigned Reg = fieldFromInstruction(Insn, 16, 5); - unsigned Base = fieldFromInstruction(Insn, 21, 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 DecodeFMem3(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - int Offset = SignExtend32<16>(Insn & 0xffff); - unsigned Reg = fieldFromInstruction(Insn, 16, 5); - unsigned Base = fieldFromInstruction(Insn, 21, 5); - - 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)); - - 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 DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn, - uint64_t Address, const void *Decoder) { - int Offset = SignExtend32<11>(Insn & 0x07ff); - unsigned Reg = fieldFromInstruction(Insn, 21, 5); - unsigned Base = fieldFromInstruction(Insn, 16, 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, - const void *Decoder) { - int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff); - unsigned Rt = fieldFromInstruction(Insn, 16, 5); - unsigned Base = fieldFromInstruction(Insn, 21, 5); - - Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt); - 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(Base)); - Inst.addOperand(MCOperand::createImm(Offset)); - - return MCDisassembler::Success; -} - -static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - // Currently only hardware register 29 is supported. - if (RegNo != 29) - return MCDisassembler::Fail; - Inst.addOperand(MCOperand::createReg(Mips::HWR29)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 30 || RegNo %2) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo >= 4) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo >= 4) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo >= 4) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 31) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 31) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 31) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 31) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 7) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo); - 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; -} - -static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { - if (RegNo > 31) - return MCDisassembler::Fail; - - unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo); - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeBranchTarget(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder) { - int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4; - Inst.addOperand(MCOperand::createImm(BranchOffset)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder) { - int32_t BranchOffset = (SignExtend32<16>(Offset) * 2); - Inst.addOperand(MCOperand::createImm(BranchOffset)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeJumpTarget(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; - Inst.addOperand(MCOperand::createImm(JumpOffset)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeBranchTarget21(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder) { - int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4; - - Inst.addOperand(MCOperand::createImm(BranchOffset)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder) { - int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4; - - Inst.addOperand(MCOperand::createImm(BranchOffset)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeBranchTarget26(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder) { - int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4; - - 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<8>(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<11>(Offset << 1); - Inst.addOperand(MCOperand::createImm(BranchOffset)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder) { - int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4; - Inst.addOperand(MCOperand::createImm(BranchOffset)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder) { - int32_t BranchOffset = SignExtend32<27>(Offset << 1); - - Inst.addOperand(MCOperand::createImm(BranchOffset)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1; - 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 DecodeLi16Imm(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 DecodePOOL16BEncodedField(MCInst &Inst, - unsigned Value, - uint64_t Address, - const void *Decoder) { - Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value)); - return MCDisassembler::Success; -} - -template <unsigned Bits, int Offset, int Scale> -static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, - uint64_t Address, - const void *Decoder) { - Value &= ((1 << Bits) - 1); - Value *= Scale; - Inst.addOperand(MCOperand::createImm(Value + Offset)); - return MCDisassembler::Success; -} - -template <unsigned Bits, int Offset, int ScaleBy> -static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value, - uint64_t Address, - const void *Decoder) { - int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy; - Inst.addOperand(MCOperand::createImm(Imm + Offset)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeInsSize(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - // First we need to grab the pos(lsb) from MCInst. - // This function only handles the 32 bit variants of ins, as dins - // variants are handled differently. - int Pos = Inst.getOperand(2).getImm(); - int Size = (int) Insn - Pos + 1; - 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)); - return MCDisassembler::Success; -} - -static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, - uint64_t Address, const void *Decoder) { - 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 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::S7, 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; - - // RegLst values 10-15, and 26-31 are reserved. - if (RegNum > 9) - return MCDisassembler::Fail; - - 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; - switch(Inst.getOpcode()) { - default: - RegLst = fieldFromInstruction(Insn, 4, 2); - break; - case Mips::LWM16_MMR6: - case Mips::SWM16_MMR6: - RegLst = fieldFromInstruction(Insn, 8, 2); - break; - } - 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 DecodeMovePOperands(MCInst &Inst, unsigned Insn, - uint64_t Address, - const void *Decoder) { - unsigned RegPair = fieldFromInstruction(Insn, 7, 3); - if (DecodeMovePRegPair(Inst, RegPair, Address, Decoder) == - MCDisassembler::Fail) - return MCDisassembler::Fail; - - unsigned RegRs; - if (static_cast<const MipsDisassembler*>(Decoder)->hasMips32r6()) - RegRs = fieldFromInstruction(Insn, 0, 2) | - (fieldFromInstruction(Insn, 3, 1) << 2); - else - RegRs = fieldFromInstruction(Insn, 1, 3); - if (DecodeGPRMM16MovePRegisterClass(Inst, RegRs, Address, Decoder) == - MCDisassembler::Fail) - return MCDisassembler::Fail; - - unsigned RegRt = fieldFromInstruction(Insn, 4, 3); - if (DecodeGPRMM16MovePRegisterClass(Inst, RegRt, Address, Decoder) == - MCDisassembler::Fail) - return MCDisassembler::Fail; - - return MCDisassembler::Success; -} - -static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair, - uint64_t Address, const void *Decoder) { - 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; -} - -template <typename InsnType> -static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, - uint64_t Address, - const void *Decoder) { - // We have: - // 0b000111 ttttt sssss iiiiiiiiiiiiiiii - // Invalid if rt == 0 - // BGTZALC_MMR6 if rs == 0 && rt != 0 - // BLTZALC_MMR6 if rs != 0 && rs == rt - // BLTUC_MMR6 if rs != 0 && rs != rt - - InsnType Rt = fieldFromInstruction(insn, 21, 5); - InsnType Rs = fieldFromInstruction(insn, 16, 5); - InsnType Imm = 0; - bool HasRs = false; - bool HasRt = false; - - if (Rt == 0) - return MCDisassembler::Fail; - else if (Rs == 0) { - MI.setOpcode(Mips::BGTZALC_MMR6); - HasRt = true; - Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; - } - else if (Rs == Rt) { - MI.setOpcode(Mips::BLTZALC_MMR6); - HasRs = true; - Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; - } - else { - MI.setOpcode(Mips::BLTUC_MMR6); - HasRs = true; - HasRt = true; - Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; - } - - if (HasRs) - MI.addOperand( - MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); - - if (HasRt) - MI.addOperand( - MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); - - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} - -template <typename InsnType> -static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, - uint64_t Address, - const void *Decoder) { - // We have: - // 0b000110 ttttt sssss iiiiiiiiiiiiiiii - // Invalid if rt == 0 - // BLEZALC_MMR6 if rs == 0 && rt != 0 - // BGEZALC_MMR6 if rs == rt && rt != 0 - // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0 - - InsnType Rt = fieldFromInstruction(insn, 21, 5); - InsnType Rs = fieldFromInstruction(insn, 16, 5); - InsnType Imm = 0; - bool HasRs = false; - - if (Rt == 0) - return MCDisassembler::Fail; - else if (Rs == 0) { - MI.setOpcode(Mips::BLEZALC_MMR6); - Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; - } - else if (Rs == Rt) { - MI.setOpcode(Mips::BGEZALC_MMR6); - Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; - } - else { - HasRs = true; - MI.setOpcode(Mips::BGEUC_MMR6); - Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; - } - - if (HasRs) - MI.addOperand( - MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); - MI.addOperand( - MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); - - MI.addOperand(MCOperand::createImm(Imm)); - - return MCDisassembler::Success; -} |