From 57b661793994569788904489b56c8431e0523328 Mon Sep 17 00:00:00 2001 From: Nitr0-G <120374383+Nitr0-G@users.noreply.github.com> Date: Wed, 26 Apr 2023 21:01:24 +0300 Subject: [PATCH 1/5] Intel MPX support Skipping all MPX instructions has been added in order to eliminate bugs caused on these Issues https://github.com/avast/retdec/issues/1148 https://github.com/avast/retdec/issues/1135 Intel MPX is a dead technology that has not been supported by the Linux kernel since 2020(proof: https://www.phoronix.com/news/Intel-MPX-Is-Dead). It was only in the Skylake and Intel Goldmont(atom) architecture, consider all current processors do not support this technology. Zydis & capstone mistakenly disassembles instructions added to Intel MPX(Intel MPX adds 7 new instructions, as well as BND0-3 registers in x64 and x32 mode for more information, see here(https://intel-mpx.github.io/design /)), a tool like Hiew also does not disassemble instructions of Intel MPX (https://fpic.in/VQ9yfJ1) --- src/capstone2llvmir/capstone2llvmir_impl.cpp | 4618 +++++++++--------- 1 file changed, 2321 insertions(+), 2297 deletions(-) diff --git a/src/capstone2llvmir/capstone2llvmir_impl.cpp b/src/capstone2llvmir/capstone2llvmir_impl.cpp index 02ecca263..09481ff36 100644 --- a/src/capstone2llvmir/capstone2llvmir_impl.cpp +++ b/src/capstone2llvmir/capstone2llvmir_impl.cpp @@ -1,2297 +1,2321 @@ -/** - * @file src/capstone2llvmir/capstone2llvmir.cpp - * @brief Converts bytes to Capstone representation, and Capstone representation - * to LLVM IR. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include - -#include "capstone2llvmir/capstone2llvmir_impl.h" - -namespace retdec { -namespace capstone2llvmir { - -template -Capstone2LlvmIrTranslator_impl::Capstone2LlvmIrTranslator_impl( - cs_arch a, - cs_mode basic, - cs_mode extra, - llvm::Module* m) - : - _arch(a), - _basicMode(basic), - _extraMode(extra), - _origBasicMode(basic), - _module(m) -{ - // Do not call anything here, especially virtual methods. -} - -template -Capstone2LlvmIrTranslator_impl::~Capstone2LlvmIrTranslator_impl() -{ - closeHandle(); -} - -// -//============================================================================== -// Translator configuration methods. -//============================================================================== -// - -template -void Capstone2LlvmIrTranslator_impl::setIgnoreUnexpectedOperands(bool f) -{ - _ignoreUnexpectedOperands = f; -} - -template -void Capstone2LlvmIrTranslator_impl::setIgnoreUnhandledInstructions(bool f) -{ - _ignoreUnhandledInstructions = f; -} - -template -void Capstone2LlvmIrTranslator_impl::setGeneratePseudoAsmFunctions(bool f) -{ - _generatePseudoAsmFunctions = f; -} - -template -bool Capstone2LlvmIrTranslator_impl::isIgnoreUnexpectedOperands() const -{ - return _ignoreUnexpectedOperands; -} - -template -bool Capstone2LlvmIrTranslator_impl::isIgnoreUnhandledInstructions() const -{ - return _ignoreUnhandledInstructions; -} - -template -bool Capstone2LlvmIrTranslator_impl::isGeneratePseudoAsmFunctions() const -{ - return _generatePseudoAsmFunctions; -} - -// -//============================================================================== -// Mode query & modification methods - from Capstone2LlvmIrTranslator. -//============================================================================== -// - -template -void Capstone2LlvmIrTranslator_impl::modifyBasicMode(cs_mode m) -{ - if (!isAllowedBasicMode(m)) - { - throw ModeSettingError( - _arch, - m, - ModeSettingError::eType::BASIC_MODE); - } - - if (cs_option(_handle, CS_OPT_MODE, m + _extraMode) != CS_ERR_OK) - { - throw CapstoneError(cs_errno(_handle)); - } - - _basicMode = m; -} - -template -void Capstone2LlvmIrTranslator_impl::modifyExtraMode(cs_mode m) -{ - if (!isAllowedExtraMode(m)) - { - throw ModeSettingError( - _arch, - m, - ModeSettingError::eType::EXTRA_MODE); - } - - if (cs_option(_handle, CS_OPT_MODE, m + _basicMode) != CS_ERR_OK) - { - throw CapstoneError(cs_errno(_handle)); - } - - _extraMode = m; -} - -template -uint32_t Capstone2LlvmIrTranslator_impl::getArchBitSize() -{ - return getArchByteSize() * 8; -} - -// -//============================================================================== -// Translation methods - from Capstone2LlvmIrTranslator. -//============================================================================== -// - -// TODO: Optimize -- to make generation easier and nicer, some things -// can be generated suboptimally. We should inspect every generated -// ASM insruction and optimize some known patterns: -// -// 1. Load propagation: -// a = load r -// ... use a, not change r, no fnc call, etc. -// b = load r -// ... use b -> replace by a, remove b -// -// 2. Conversions: -// a = cast b -// ... use a -// c = cast b -// ... use c -> replace by a, remove c -// -// 3. Unused values (e.g. from loadOpBinary() where only one op used): -// a = load x -// ... a unused -// -// 4. Values used only for their type (e.g. op0 load in translateMov()): -// a = load x -// b = load y -// c = convert b to a.type -// store c x -// -// etc. - -template -typename Capstone2LlvmIrTranslator_impl::TranslationResult -Capstone2LlvmIrTranslator_impl::translate( - const uint8_t* bytes, - std::size_t size, - retdec::common::Address a, - llvm::IRBuilder<>& irb, - std::size_t count, - bool stopOnBranch) -{ - TranslationResult res; - - // We want to keep all Capstone instructions -> alloc a new one each time. - cs_insn* insn = cs_malloc(_handle); - - uint64_t address = a; - - _branchGenerated = nullptr; - _inCondition = false; - - // TODO: hack, solve better. - bool disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) - { - modifyBasicMode(CS_MODE_MIPS64); - disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - modifyBasicMode(CS_MODE_MIPS32); - } - - while (disasmRes) - { - auto* a2l = generateSpecialAsm2LlvmInstr(irb, insn); - - res.insns.push_back(std::make_pair(a2l, insn)); - res.size = (insn->address + insn->size) - a; - - translateInstruction(insn, irb); - - ++res.count; - if (count && count == res.count) - { - return res; - } - - if (_branchGenerated && stopOnBranch) - { - res.branchCall = _branchGenerated; - res.inCondition = _inCondition; - return res; - } - - insn = cs_malloc(_handle); - - // TODO: hack, solve better. - disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) - { - modifyBasicMode(CS_MODE_MIPS64); - disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - modifyBasicMode(CS_MODE_MIPS32); - } - } - - cs_free(insn, 1); - - return res; -} - -template -typename Capstone2LlvmIrTranslator_impl::TranslationResultOne -Capstone2LlvmIrTranslator_impl::translateOne( - const uint8_t*& bytes, - std::size_t& size, - retdec::common::Address& a, - llvm::IRBuilder<>& irb) -{ - TranslationResultOne res; - - // We want to keep all Capstone instructions -> alloc a new one each time. - cs_insn* insn = cs_malloc(_handle); - - uint64_t address = a; - _branchGenerated = nullptr; - _inCondition = false; - - // TODO: hack, solve better. - bool disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) - { - modifyBasicMode(CS_MODE_MIPS64); - disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - modifyBasicMode(CS_MODE_MIPS32); - } - - if (disasmRes) - { - auto* a2l = generateSpecialAsm2LlvmInstr(irb, insn); - translateInstruction(insn, irb); - - res.llvmInsn = a2l; - res.capstoneInsn = insn; - res.size = insn->size; - res.branchCall = _branchGenerated; - res.inCondition = _inCondition; - - a = address; - } - else - { - cs_free(insn, 1); - } - - return res; -} - -// -//============================================================================== -// Capstone related getters - from Capstone2LlvmIrTranslator. -//============================================================================== -// - -template -const csh& Capstone2LlvmIrTranslator_impl::getCapstoneEngine() const -{ - return _handle; -} - -template -cs_arch Capstone2LlvmIrTranslator_impl::getArchitecture() const -{ - return _arch; -} - -template -cs_mode Capstone2LlvmIrTranslator_impl::getBasicMode() const -{ - return _basicMode; -} - -template -cs_mode Capstone2LlvmIrTranslator_impl::getExtraMode() const -{ - return _extraMode; -} - -template -bool Capstone2LlvmIrTranslator_impl::hasDelaySlot(uint32_t id) const -{ - return false; -} - -template -bool Capstone2LlvmIrTranslator_impl::hasDelaySlotTypical(uint32_t id) const -{ - return false; -} - -template -bool Capstone2LlvmIrTranslator_impl::hasDelaySlotLikely(uint32_t id) const -{ - return false; -} - -template -std::size_t Capstone2LlvmIrTranslator_impl::getDelaySlot(uint32_t id) const -{ - return 0; -} - -template -llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::getRegister(uint32_t r) -{ - auto fIt = _capstone2LlvmRegs.find(r); - return fIt != _capstone2LlvmRegs.end() ? fIt->second : nullptr; -} - -template -std::string Capstone2LlvmIrTranslator_impl::getRegisterName(uint32_t r) const -{ - auto fIt = _reg2name.find(r); - if (fIt == _reg2name.end()) - { - if (auto* n = cs_reg_name(_handle, r)) - { - return n; - } - else - { - throw GenericError( - "Missing name for register number: " + std::to_string(r)); - } - } - else - { - return fIt->second; - } -} - -template -uint32_t Capstone2LlvmIrTranslator_impl::getRegisterBitSize(uint32_t r) const -{ - auto* rt = getRegisterType(r); - if (auto* it = llvm::dyn_cast(rt)) - { - return it->getBitWidth(); - } - else if (rt->isHalfTy()) - { - return 16; - } - else if (rt->isFloatTy()) - { - return 32; - } - else if (rt->isDoubleTy()) - { - return 64; - } - else if (rt->isX86_FP80Ty()) - { - return 80; - } - else if (rt->isFP128Ty()) - { - return 128; - } - else - { - throw GenericError( - "Unhandled type of register number: " + std::to_string(r)); - } -} - -template -uint32_t Capstone2LlvmIrTranslator_impl::getRegisterByteSize( - uint32_t r) const -{ - return getRegisterBitSize(r) / 8; -} - -template -llvm::Type* Capstone2LlvmIrTranslator_impl::getRegisterType( - uint32_t r) const -{ - auto fIt = _reg2type.find(r); - if (fIt == _reg2type.end()) - { - throw GenericError( - "Missing type for register number: " + std::to_string(r)); - } - return fIt->second; -} - -template -bool Capstone2LlvmIrTranslator_impl::isControlFlowInstruction( - cs_insn& i) const -{ - return _controlFlowInsnIds.count(i.id) - || isCallInstruction(i) - || isReturnInstruction(i) - || isBranchInstruction(i) - || isCondBranchInstruction(i); -} - -template -bool Capstone2LlvmIrTranslator_impl::isCallInstruction( - cs_insn& i) const -{ - return _callInsnIds.count(i.id); -} - -template -bool Capstone2LlvmIrTranslator_impl::isReturnInstruction( - cs_insn& i) const -{ - return _returnInsnIds.count(i.id); -} - -template -bool Capstone2LlvmIrTranslator_impl::isBranchInstruction( - cs_insn& i) const -{ - return _branchInsnIds.count(i.id); -} - -template -bool Capstone2LlvmIrTranslator_impl::isCondBranchInstruction( - cs_insn& i) const -{ - return _condBranchInsnIds.count(i.id); -} - -// -//============================================================================== -// LLVM related getters and query methods. -//============================================================================== -// - -template -llvm::BranchInst* -Capstone2LlvmIrTranslator_impl::getCondBranchForInsnInIfThen( - llvm::Instruction* i) const -{ - // Asm to LLVM mapping instruction is not in BB where call is. - auto* prev = i->getPrevNode(); - while (prev) - { - if (isSpecialAsm2LlvmInstr(prev)) - { - return nullptr; - } - prev = prev->getPrevNode(); - } - - auto* prevBb = i->getParent()->getPrevNode(); - auto* term = prevBb ? prevBb->getTerminator() : nullptr; - auto* br = llvm::dyn_cast_or_null(term); - if (prevBb == nullptr - || br == nullptr - || !br->isConditional() - || br->getSuccessor(0) != i->getParent()) - { - return nullptr; - } - - return br; -} - -template -llvm::Module* Capstone2LlvmIrTranslator_impl::getModule() const -{ - return _module; -} - -template -bool Capstone2LlvmIrTranslator_impl::isSpecialAsm2LlvmMapGlobal( - llvm::Value* v) const -{ - return _asm2llvmGv == v; -} - -template -llvm::StoreInst* Capstone2LlvmIrTranslator_impl::isSpecialAsm2LlvmInstr( - llvm::Value* v) const -{ - if (auto* s = llvm::dyn_cast(v)) - { - if (isSpecialAsm2LlvmMapGlobal(s->getPointerOperand())) - { - return s; - } - } - return nullptr; -} - -template -llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::getAsm2LlvmMapGlobalVariable() const -{ - return _asm2llvmGv; -} - -template -bool Capstone2LlvmIrTranslator_impl::isCallFunction(llvm::Function* f) const -{ - return f == _callFunction; -} - -template -bool Capstone2LlvmIrTranslator_impl::isCallFunctionCall(llvm::CallInst* c) const -{ - return c ? isCallFunction(c->getCalledFunction()) : false; -} - -template -llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionCallFunctionCall(llvm::CallInst* c) const -{ - return isCallFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; -} - -template -llvm::Function* Capstone2LlvmIrTranslator_impl::getCallFunction() const -{ - return _callFunction; -} - -template -bool Capstone2LlvmIrTranslator_impl::isReturnFunction(llvm::Function* f) const -{ - return f == _returnFunction; -} - -template -bool Capstone2LlvmIrTranslator_impl::isReturnFunctionCall( - llvm::CallInst* c) const -{ - return c ? isReturnFunction(c->getCalledFunction()) : false; -} - -template -llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionReturnFunctionCall(llvm::CallInst* c) const -{ - return isReturnFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; -} - -template -llvm::Function* Capstone2LlvmIrTranslator_impl::getReturnFunction() const -{ - return _returnFunction; -} - -template -bool Capstone2LlvmIrTranslator_impl::isBranchFunction(llvm::Function* f) const -{ - return _branchFunction == f; -} - -template -bool Capstone2LlvmIrTranslator_impl::isBranchFunctionCall( - llvm::CallInst* c) const -{ - return c ? isBranchFunction(c->getCalledFunction()) : false; -} - -template -llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionBranchFunctionCall(llvm::CallInst* c) const -{ - return isBranchFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; -} - -template -llvm::Function* Capstone2LlvmIrTranslator_impl::getBranchFunction() const -{ - return _branchFunction; -} - -template -bool Capstone2LlvmIrTranslator_impl::isCondBranchFunction( - llvm::Function* f) const -{ - return _condBranchFunction == f; -} - -template -bool Capstone2LlvmIrTranslator_impl::isCondBranchFunctionCall( - llvm::CallInst* c) const -{ - return c ? isCondBranchFunction(c->getCalledFunction()) : false; -} - -template -llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionCondBranchFunctionCall( - llvm::CallInst* c) const -{ - return isCondBranchFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; -} - -template -llvm::Function* Capstone2LlvmIrTranslator_impl::getCondBranchFunction() const -{ - return _condBranchFunction; -} - -template -bool Capstone2LlvmIrTranslator_impl::isAnyPseudoFunction( - llvm::Function* f) const -{ - return isCallFunction(f) - || isReturnFunction(f) - || isBranchFunction(f) - || isCondBranchFunction(f); -} - -template -bool Capstone2LlvmIrTranslator_impl::isAnyPseudoFunctionCall( - llvm::CallInst* c) const -{ - return isCallFunctionCall(c) - || isReturnFunctionCall(c) - || isBranchFunctionCall(c) - || isCondBranchFunctionCall(c); -} - -template -llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::isRegister( - llvm::Value* v) const -{ - auto it = _llvm2CapstoneRegs.find(llvm::dyn_cast_or_null(v)); - return it != _llvm2CapstoneRegs.end() ? it->first : nullptr; -} - -template -uint32_t Capstone2LlvmIrTranslator_impl::getCapstoneRegister( - llvm::GlobalVariable* gv) const -{ - auto it = _llvm2CapstoneRegs.find(gv); - return it != _llvm2CapstoneRegs.end() ? it->second : 0; -} - -template -bool Capstone2LlvmIrTranslator_impl::isPseudoAsmFunction( - llvm::Function* f) const -{ - return _asmFunctions.count(f); -} - -template -bool Capstone2LlvmIrTranslator_impl::isPseudoAsmFunctionCall( - llvm::CallInst* c) const -{ - return c ? isPseudoAsmFunction(c->getCalledFunction()) : false; -} - -template -const std::set& Capstone2LlvmIrTranslator_impl::getPseudoAsmFunctions() const -{ - return _asmFunctions; -} - -// -//============================================================================== -// -//============================================================================== -// - -template -void Capstone2LlvmIrTranslator_impl::initialize() -{ - if (!isAllowedBasicMode(_basicMode)) - { - throw ModeSettingError( - _arch, - _basicMode, - ModeSettingError::eType::BASIC_MODE); - } - if (!isAllowedExtraMode(_extraMode)) - { - throw ModeSettingError( - _arch, - _extraMode, - ModeSettingError::eType::EXTRA_MODE); - } - - openHandle(); // Sets both _basicMode and _extraMode. - configureHandle(); - - initializeRegNameMap(); - initializeRegTypeMap(); - initializePseudoCallInstructionIDs(); - initializeArchSpecific(); - - generateEnvironment(); -} - -template -void Capstone2LlvmIrTranslator_impl::openHandle() -{ - cs_mode finalMode = static_cast(_basicMode + _extraMode); - if (cs_open(_arch, finalMode, &_handle) != CS_ERR_OK) - { - throw CapstoneError(cs_errno(_handle)); - } -} - -template -void Capstone2LlvmIrTranslator_impl::configureHandle() -{ - if (cs_option(_handle, CS_OPT_DETAIL, CS_OPT_ON) != CS_ERR_OK) - { - throw CapstoneError(cs_errno(_handle)); - } -} - -template -void Capstone2LlvmIrTranslator_impl::closeHandle() -{ - if (_handle != 0) - { - if (cs_close(&_handle) != CS_ERR_OK) - { - throw CapstoneError(cs_errno(_handle)); - } - } -} - -template -void Capstone2LlvmIrTranslator_impl::generateEnvironment() -{ - generateSpecialAsm2LlvmMapGlobal(); - generateCallFunction(); - generateReturnFunction(); - generateBranchFunction(); - generateCondBranchFunction(); - - generateEnvironmentArchSpecific(); - generateRegisters(); - generateDataLayout(); -} - -/** - * The generated global variable is unnamed. capstone2llvmir library does not - * allow to specify or set its name. Users can however get the variable with - * @c getAsm2LlvmMapGlobalVariable() and do whatever they want with it - * (e.g. rename). - */ -template -void Capstone2LlvmIrTranslator_impl::generateSpecialAsm2LlvmMapGlobal() -{ - llvm::GlobalValue::LinkageTypes lt = llvm::GlobalValue::InternalLinkage; - llvm::Constant* initializer = nullptr; - auto* t = llvm::IntegerType::getInt64Ty(_module->getContext()); - if (initializer == nullptr - && lt != llvm::GlobalValue::LinkageTypes::ExternalLinkage) - { - initializer = llvm::ConstantInt::get(t, 0); - } - - _asm2llvmGv = new llvm::GlobalVariable( - *_module, - t, - false, // isConstant - lt, - initializer); -} - -template -llvm::StoreInst* Capstone2LlvmIrTranslator_impl::generateSpecialAsm2LlvmInstr( - llvm::IRBuilder<>& irb, - cs_insn* i) -{ - retdec::common::Address a = i->address; - auto* gv = getAsm2LlvmMapGlobalVariable(); - auto* ci = llvm::ConstantInt::get(gv->getValueType(), a, false); - auto* s = irb.CreateStore(ci, gv, true); - return s; -} - -template -void Capstone2LlvmIrTranslator_impl::generateCallFunction() -{ - auto* ft = llvm::FunctionType::get( - llvm::Type::getVoidTy(_module->getContext()), - {llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}, - false); - _callFunction = llvm::Function::Create( - ft, - llvm::GlobalValue::LinkageTypes::ExternalLinkage, - "", - _module); -} - -template -llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCallFunctionCall( - llvm::IRBuilder<>& irb, - llvm::Value* t) -{ - auto* a1t = _callFunction->arg_begin()->getType(); - t = irb.CreateSExtOrTrunc(t, a1t); - _branchGenerated = irb.CreateCall(_callFunction, {t}); - return _branchGenerated; -} - -template -llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCondCallFunctionCall( - llvm::IRBuilder<>& irb, - llvm::Value* cond, - llvm::Value* t) -{ - auto bodyIrb = generateIfThen(cond, irb); - - auto* a1t = _callFunction->arg_begin()->getType(); - t = bodyIrb.CreateSExtOrTrunc(t, a1t); - _branchGenerated = bodyIrb.CreateCall(_callFunction, {t}); - _inCondition = true; - return _branchGenerated; -} - -template -void Capstone2LlvmIrTranslator_impl::generateReturnFunction() -{ - auto* ft = llvm::FunctionType::get( - llvm::Type::getVoidTy(_module->getContext()), - {llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}, - false); - _returnFunction = llvm::Function::Create( - ft, - llvm::GlobalValue::LinkageTypes::ExternalLinkage, - "", - _module); -} - -template -llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateReturnFunctionCall( - llvm::IRBuilder<>& irb, - llvm::Value* t) -{ - auto* a1t = _returnFunction->arg_begin()->getType(); - t = irb.CreateSExtOrTrunc(t, a1t); - _branchGenerated = irb.CreateCall(_returnFunction, {t}); - return _branchGenerated; -} - -template -llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCondReturnFunctionCall( - llvm::IRBuilder<>& irb, - llvm::Value* cond, - llvm::Value* t) -{ - auto bodyIrb = generateIfThen(cond, irb); - - auto* a1t = _returnFunction->arg_begin()->getType(); - t = bodyIrb.CreateSExtOrTrunc(t, a1t); - _branchGenerated = bodyIrb.CreateCall(_returnFunction, {t}); - _inCondition = true; - return _branchGenerated; -} - -template -void Capstone2LlvmIrTranslator_impl::generateBranchFunction() -{ - auto* ft = llvm::FunctionType::get( - llvm::Type::getVoidTy(_module->getContext()), - {llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}, - false); - _branchFunction = llvm::Function::Create( - ft, - llvm::GlobalValue::LinkageTypes::ExternalLinkage, - "", - _module); -} - -template -llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateBranchFunctionCall( - llvm::IRBuilder<>& irb, - llvm::Value* t) -{ - auto* a1t = _branchFunction->arg_begin()->getType(); - t = irb.CreateSExtOrTrunc(t, a1t); - _branchGenerated = irb.CreateCall(_branchFunction, {t}); - return _branchGenerated; -} - -template -void Capstone2LlvmIrTranslator_impl::generateCondBranchFunction() -{ - std::vector params = { - llvm::Type::getInt1Ty(_module->getContext()), - llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}; - auto* ft = llvm::FunctionType::get( - llvm::Type::getVoidTy(_module->getContext()), - params, - false); - _condBranchFunction = llvm::Function::Create( - ft, - llvm::GlobalValue::LinkageTypes::ExternalLinkage, - "", - _module); -} - -template -llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCondBranchFunctionCall( - llvm::IRBuilder<>& irb, - llvm::Value* cond, - llvm::Value* t) -{ - auto aIt = _condBranchFunction->arg_begin(); - ++aIt; - auto* a1t = aIt->getType(); - t = irb.CreateSExtOrTrunc(t, a1t); - _branchGenerated = irb.CreateCall(_condBranchFunction, {cond, t}); - return _branchGenerated; -} - -template -llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::createRegister( - uint32_t r, - llvm::GlobalValue::LinkageTypes lt, - llvm::Constant* initializer) -{ - auto* rt = getRegisterType(r); - if (initializer == nullptr - && lt != llvm::GlobalValue::LinkageTypes::ExternalLinkage) - { - if (auto* it = llvm::dyn_cast(rt)) - { - initializer = llvm::ConstantInt::get(it, 0); - } - else if (rt->isFloatingPointTy()) - { - initializer = llvm::ConstantFP::get(rt, 0); - } - else - { - throw GenericError("Unhandled register type."); - } - } - - auto* gv = new llvm::GlobalVariable( - *_module, - rt, - false, // isConstant - lt, - initializer, - getRegisterName(r)); - - if (gv == nullptr) - { - throw GenericError("Memory allocation error."); - } - - _llvm2CapstoneRegs[gv] = r; - _capstone2LlvmRegs[r] = gv; - - return gv; -} - -// -//============================================================================== -// Load/store methods. -//============================================================================== -// - -template -llvm::Value* Capstone2LlvmIrTranslator_impl::loadOp( - CInsn* ci, - llvm::IRBuilder<>& irb, - std::size_t idx, - llvm::Type* loadType, - llvm::Type* dstType, - eOpConv ct) -{ - if (ci->op_count <= idx) - { - throw GenericError( - "Idx out of bounds: "+std::to_string(idx) - +"/"+std::to_string(ci->op_count)); - } - - auto* op = loadOp(ci->operands[idx], irb, loadType); - if (op == nullptr) - { - throw GenericError("Operand loading failed."); - } - - if (dstType == nullptr) - { - return op; - } - - return generateTypeConversion(irb, op, dstType, ct); -} - -template -std::vector Capstone2LlvmIrTranslator_impl::_loadOps( - CInsn* ci, - llvm::IRBuilder<>& irb, - std::size_t opCnt, - bool strict, - llvm::Type* loadType, - llvm::Type* dstType, - eOpConv ct) -{ - if ((strict && (ci->op_count != opCnt)) || (ci->op_count < opCnt)) - { - throw GenericError( - "Trying to load " - +std::to_string(opCnt) - +" operands from instruction with" - +std::to_string(ci->op_count) - +" opernads."); - } - - std::size_t startOp = ci->op_count - opCnt; - - std::vector operands; - - // If no destination type specified, use type of first operand. - if (dstType == nullptr) - { - auto* op0 = loadOp(ci, irb, startOp, loadType, dstType, ct); - dstType = op0->getType(); - dstType = _checkTypeConversion(irb, dstType, ct); - op0 = generateTypeConversion(irb, op0, dstType, ct); - startOp++; - operands.push_back(op0); - } - else - { - auto* type = _checkTypeConversion(irb, dstType, ct); - if (type != dstType) - { - throw GenericError( - "Invalid combination of destination type and conversion type."); - } - } - - for (; startOp < ci->op_count; startOp++) { - auto* op = loadOp(ci, irb, startOp, loadType, dstType, ct); - operands.push_back(op); - } - - return operands; -} - -template -std::vector -Capstone2LlvmIrTranslator_impl::_loadOpsUniversal( - CInsn* ci, - llvm::IRBuilder<>& irb, - std::size_t opCnt, - bool strict, - eOpConv ict, - eOpConv fct) -{ - if ((strict && (ci->op_count != opCnt)) || (ci->op_count < opCnt)) - { - throw GenericError( - "Trying to load " - +std::to_string(opCnt) - +" operands from instruction with" - +std::to_string(ci->op_count) - +" opernads."); - } - - auto op0 = loadOp(ci, irb, ci->op_count - opCnt); - if (op0->getType()->isIntegerTy()) - { - auto operands = _loadOps(ci, irb, opCnt-1, false, nullptr, op0->getType(), ict); - operands.insert(operands.begin(), op0); - return operands; - } - - auto operands = _loadOps(ci, irb, opCnt-1, false, nullptr, op0->getType(), fct); - operands.insert(operands.begin(), op0); - return operands; -} - -/** - * Throws if op_count != 1. - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::loadOpUnary( - CInsn* ci, - llvm::IRBuilder<>& irb, - llvm::Type* loadType, - llvm::Type* dstType, - eOpConv ct) -{ - return _loadOps(ci, irb, 1, true, loadType, dstType, ct)[0]; -} - -/** - * Throws if op_count != 2. - */ -template -std::pair -Capstone2LlvmIrTranslator_impl::loadOpBinary( - CInsn* ci, - llvm::IRBuilder<>& irb, - eOpConv ct) -{ - auto operands = _loadOps(ci, irb, 2, true, nullptr, nullptr, ct); - return std::make_pair(operands[0], operands[1]); -} - -/** - * Throws if op_count != 2. - */ -template -std::pair -Capstone2LlvmIrTranslator_impl::loadOpBinary( - CInsn* ci, - llvm::IRBuilder<>& irb, - eOpConv ict, - eOpConv fct) -{ - auto operands = _loadOpsUniversal(ci, irb, 2, true, ict, fct); - return std::make_pair(operands[0], operands[1]); -} - -template -std::pair -Capstone2LlvmIrTranslator_impl::loadOpBinary( - CInsn* ci, - llvm::IRBuilder<>& irb, - llvm::Type* loadType, - llvm::Type* dstType, - eOpConv ct) -{ - auto operands = _loadOps(ci, irb, 2, true, loadType, dstType, ct); - return std::make_pair(operands[0], operands[1]); -} - -/** - * Throws if op_count != 2. - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::loadOpBinaryOp0( - CInsn* ci, - llvm::IRBuilder<>& irb, - llvm::Type* ty) -{ - auto operand = loadOp(ci, irb, 0, ty); - return operand; -} - -/** - * Throws if op_count != 2. - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::loadOpBinaryOp1( - CInsn* ci, - llvm::IRBuilder<>& irb, - llvm::Type* ty) -{ - auto operand = loadOp(ci, irb, 1, ty); - return operand; -} - -/** - * Throws if op_count != 3. - */ -template -std::tuple -Capstone2LlvmIrTranslator_impl::loadOpTernary( - CInsn* ci, - llvm::IRBuilder<>& irb, - eOpConv ct) -{ - auto operands = _loadOps(ci, irb, 3, true, nullptr, nullptr, ct); - return std::make_tuple(operands[0], operands[1], operands[2]); -} - -/** - * Throws if op_count != 3. - */ -template -std::tuple -Capstone2LlvmIrTranslator_impl::loadOpTernary( - CInsn* ci, - llvm::IRBuilder<>& irb, - eOpConv ict, - eOpConv fct) -{ - auto operands = _loadOpsUniversal(ci, irb, 3, true, ict, fct); - return std::make_tuple(operands[0], operands[1], operands[2]); -} - -/** - * Throws if op_count != 3. - */ -template -std::tuple -Capstone2LlvmIrTranslator_impl::loadOpTernary( - CInsn* ci, - llvm::IRBuilder<>& irb, - llvm::Type* loadType, - llvm::Type* dstType, - eOpConv ct) -{ - auto operands = _loadOps(ci, irb, 3, true, loadType, dstType, ct); - return std::make_tuple(operands[0], operands[1], operands[2]); -} - -/** - * Throws if op_count not in {2, 3}. - */ -template -std::pair -Capstone2LlvmIrTranslator_impl::loadOpBinaryOrTernaryOp1Op2( - CInsn* ci, - llvm::IRBuilder<>& irb, - eOpConv ct) -{ - auto operands = _loadOps(ci, irb, 2, false, nullptr, nullptr, ct); - return std::make_pair(operands[0], operands[1]); -} - -/** - * Throws if op_count not in {2, 3}. - */ -template -std::pair -Capstone2LlvmIrTranslator_impl::loadOpBinaryOrTernaryOp1Op2( - CInsn* ci, - llvm::IRBuilder<>& irb, - eOpConv ict, - eOpConv fct) -{ - auto operands = _loadOpsUniversal(ci, irb, 2, false, ict, fct); - return std::make_pair(operands[0], operands[1]); -} - -/** - * Throws if op_count != 4. - */ -template -std::tuple -Capstone2LlvmIrTranslator_impl::loadOpQuaternaryOp1Op2Op3( - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - auto operands = _loadOps(ci, irb, 3, false); - return std::make_tuple(operands[0], operands[1], operands[2]); -} - -// -//============================================================================== -// Carry/overflow/borrow add/sub generation routines. -//============================================================================== -// - -/** - * carry_add() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAdd( - llvm::Value* add, - llvm::Value* op0, - llvm::IRBuilder<>& irb) -{ - return irb.CreateICmpULT(add, op0); -} - -/** - * carry_add_c() - * - * If @p cf is not passed, default cf register is used. Why pass it? - * - Pass cf if you want to generate nicer code - prevent second cf load if - * it is already loaded by caller. This should however be taken care of by - * after generation optimizations. - * - Use a different value as cf. - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAddC( - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb, - llvm::Value* cf) -{ - auto* add1 = irb.CreateAdd(op0, op1); - if (cf == nullptr) - { - cf = loadRegister(getCarryRegister(), irb); - } - auto* cfc = irb.CreateZExtOrTrunc(cf, add1->getType()); - auto* add2 = irb.CreateAdd(add1, cfc); - auto* icmp1 = irb.CreateICmpULE(add2, op0); - auto* icmp2 = irb.CreateICmpULT(add1, op0); - auto* cff = irb.CreateZExtOrTrunc(cf, irb.getInt1Ty()); - return irb.CreateSelect(cff, icmp1, icmp2); -} - -/** - * carry_add_int4() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAddInt4( - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb) -{ - auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); - auto* and0 = irb.CreateAnd(op0, ci15); - auto* and1 = irb.CreateAnd(op1, ci15); - auto* add = irb.CreateAdd(and0, and1); - return irb.CreateICmpUGT(add, ci15); -} - -/** - * carry_add_c_int4() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAddCInt4( - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb, - llvm::Value* cf) -{ - auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); - auto* and0 = irb.CreateAnd(op0, ci15); - auto* and1 = irb.CreateAnd(op1, ci15); - auto* a = irb.CreateAdd(and0, and1); - if (cf == nullptr) - { - cf = loadRegister( - getCarryRegister(), - irb, - a->getType(), - eOpConv::ZEXT_TRUNC_OR_BITCAST); - } - auto* cfc = irb.CreateZExtOrTrunc(cf, a->getType()); - auto* add = irb.CreateAdd(a, cfc); - return irb.CreateICmpUGT(add, ci15); -} - -/** - * overflow_add() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowAdd( - llvm::Value* add, - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb) -{ - auto* xor0 = irb.CreateXor(op0, add); - auto* xor1 = irb.CreateXor(op1, add); - auto* ofAnd = irb.CreateAnd(xor0, xor1); - return irb.CreateICmpSLT( - ofAnd, - llvm::ConstantInt::get(ofAnd->getType(), 0)); -} - -/** - * overflow_add_c() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowAddC( - llvm::Value* add, - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb, - llvm::Value* cf) -{ - if (cf == nullptr) - { - cf = loadRegister(getCarryRegister(), irb); - } - auto* cfc = irb.CreateZExtOrTrunc(cf, add->getType()); - auto* ofAdd = irb.CreateAdd(add, cfc); - auto* xor0 = irb.CreateXor(op0, ofAdd); - auto* xor1 = irb.CreateXor(op1, ofAdd); - auto* ofAnd = irb.CreateAnd(xor0, xor1); - return irb.CreateICmpSLT(ofAnd, llvm::ConstantInt::get(ofAnd->getType(), 0)); -} - -/** - * overflow_sub() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowSub( - llvm::Value* sub, - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb) -{ - auto* xor0 = irb.CreateXor(op0, op1); - auto* xor1 = irb.CreateXor(op0, sub); - auto* ofAnd = irb.CreateAnd(xor0, xor1); - return irb.CreateICmpSLT( - ofAnd, - llvm::ConstantInt::get(ofAnd->getType(), 0)); -} - -/** - * overflow_sub_c() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowSubC( - llvm::Value* sub, - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb, - llvm::Value* cf) -{ - if (cf == nullptr) - { - cf = loadRegister(getCarryRegister(), irb); - } - auto* cfc = irb.CreateZExtOrTrunc(cf, sub->getType()); - auto* ofSub = irb.CreateSub(sub, cfc); - auto* xor0 = irb.CreateXor(op0, op1); - auto* xor1 = irb.CreateXor(op0, ofSub); - auto* ofAnd = irb.CreateAnd(xor0, xor1); - return irb.CreateICmpSLT( - ofAnd, - llvm::ConstantInt::get(ofAnd->getType(), 0)); -} - -/** - * borrow_sub() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSub( - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb) -{ - return irb.CreateICmpULT(op0, op1); -} - -/** - * borrow_sub_c() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSubC( - llvm::Value* sub, - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb, - llvm::Value* cf) -{ - if (cf == nullptr) - { - cf = loadRegister(getCarryRegister(), irb); - } - auto* cfc = irb.CreateZExtOrTrunc(cf, sub->getType()); - auto* cfSub = irb.CreateSub(sub, cfc); - auto* cfIcmp1 = irb.CreateICmpULT(op0, cfSub); - auto* negOne = llvm::ConstantInt::getSigned(op1->getType(), -1); - auto* cfIcmp2 = irb.CreateICmpULT(op1, negOne); - auto* cfOr = irb.CreateOr(cfIcmp1, cfIcmp2); - auto* cfIcmp3 = irb.CreateICmpULT(op0, op1); - auto* cff = irb.CreateZExtOrTrunc(cf, irb.getInt1Ty()); - return irb.CreateSelect(cff, cfOr, cfIcmp3); -} - -/** - * borrow_sub_int4() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSubInt4( - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb) -{ - auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); - auto* and0 = irb.CreateAnd(op0, ci15); - auto* and1 = irb.CreateAnd(op1, ci15); - auto* afSub = irb.CreateSub(and0, and1); - return irb.CreateICmpUGT(afSub, ci15); -} - -/** - * borrow_sub_c_int4() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSubCInt4( - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb, - llvm::Value* cf) -{ - auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); - auto* and0 = irb.CreateAnd(op0, ci15); - auto* and1 = irb.CreateAnd(op1, ci15); - auto* sub = irb.CreateSub(and0, and1); - if (cf == nullptr) - { - cf = loadRegister(getCarryRegister(), irb); - } - auto* cfc = irb.CreateZExtOrTrunc(cf, sub->getType()); - auto* add = irb.CreateAdd(sub, cfc); - return irb.CreateICmpUGT(add, ci15); -} - -// -//============================================================================== -// Non-virtual helper methods. -//============================================================================== -// - -template -llvm::IntegerType* Capstone2LlvmIrTranslator_impl::getDefaultType() -{ - return getIntegerTypeFromByteSize(_module, getArchByteSize()); -} - -template -llvm::Value* Capstone2LlvmIrTranslator_impl::getThisInsnAddress( - cs_insn* i) -{ - return llvm::ConstantInt::get(getDefaultType(), i->address); -} - -template -llvm::Value* Capstone2LlvmIrTranslator_impl::getNextInsnAddress( - cs_insn* i) -{ - return llvm::ConstantInt::get(getDefaultType(), i->address + i->size); -} - -/** - * Generate pseudo assembly function name from the given instruction @a insn. - */ -template -std::string Capstone2LlvmIrTranslator_impl::getPseudoAsmFunctionName( - cs_insn* insn) -{ - return "__asm_" + std::string(insn->mnemonic); -} - -/** - * Get already existing asm functions associated with @p name, or if there - * is no such function, create it using @p name and @p type, add it to asm - * functions and return it. - * @return Functions associated with @p insnId. - */ -template -llvm::Function* Capstone2LlvmIrTranslator_impl::getPseudoAsmFunction( - cs_insn* insn, - llvm::FunctionType* type, - const std::string& name) -{ - auto n = name.empty() ? getPseudoAsmFunctionName(insn) : name; - auto p = std::make_pair(n, type); - auto fIt = _insn2asmFunctions.find(p); - if (fIt == _insn2asmFunctions.end()) - { - auto* fnc = llvm::Function::Create( - type, - llvm::GlobalValue::LinkageTypes::ExternalLinkage, - n, - _module); - _insn2asmFunctions[p] = fnc; - _asmFunctions.insert(fnc); - return fnc; - } - else - { - return fIt->second; - } -} - -/** - * The same as @c getPseudoAsmFunction(std::size_t,std::string&, llvm::FunctionType*), - * but function type is created by this variant. - */ -template -llvm::Function* Capstone2LlvmIrTranslator_impl::getPseudoAsmFunction( - cs_insn* insn, - llvm::Type* retType, - llvm::ArrayRef params, - const std::string& name) -{ - return getPseudoAsmFunction( - insn, - llvm::FunctionType::get(retType, params, false), - name); -} - -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateTypeConversion( - llvm::IRBuilder<>& irb, - llvm::Value* from, - llvm::Type* to, - eOpConv ct) -{ - if (to == nullptr || from->getType() == to) - { - return from; - } - - llvm::Value* ret = nullptr; - - switch (ct) - { - case eOpConv::SEXT_TRUNC_OR_BITCAST: - { - if (!to->isIntegerTy()) - { - throw GenericError("Invalid combination of conversion method and destination type"); - } - - if (from->getType()->isIntegerTy()) - { - ret = irb.CreateSExtOrTrunc(from, to); - } - else - { - auto size = _module->getDataLayout().getTypeStoreSizeInBits(from->getType()); - auto intTy = irb.getIntNTy(size); - ret = irb.CreateBitCast(from, intTy); - ret = irb.CreateZExtOrTrunc(ret, to); - } - break; - } - case eOpConv::ZEXT_TRUNC_OR_BITCAST: - { - if (!to->isIntegerTy()) - { - throw GenericError("Invalid combination of conversion method and destination type"); - } - - if (from->getType()->isIntegerTy()) - { - ret = irb.CreateZExtOrTrunc(from, to); - } - else - { - auto size = _module->getDataLayout().getTypeStoreSizeInBits(from->getType()); - auto intTy = irb.getIntNTy(size); - ret = irb.CreateBitCast(from, intTy); - ret = irb.CreateZExtOrTrunc(ret, to); - } - break; - } - case eOpConv::FPCAST_OR_BITCAST: - { - if (!to->isFloatingPointTy()) - { - throw GenericError("Invalid combination of conversion method and destination type"); - } - - if (from->getType()->isFloatingPointTy()) - { - ret = irb.CreateFPCast(from, to); - } - else - { - auto isize = _module->getDataLayout().getTypeStoreSizeInBits(from->getType()); - auto dsize = _module->getDataLayout().getTypeStoreSizeInBits(irb.getDoubleTy()); - auto fsize = _module->getDataLayout().getTypeStoreSizeInBits(irb.getFloatTy()); - auto lsize = _module->getDataLayout().getTypeStoreSizeInBits(llvm::Type::getFP128Ty(_module->getContext())); - - if (isize == fsize) - { - from = irb.CreateBitCast(from, irb.getFloatTy()); - } - else if (isize == dsize) - { - from = irb.CreateBitCast(from, irb.getDoubleTy()); - } - else if (isize == lsize) - { - from = irb.CreateBitCast(from, llvm::Type::getFP128Ty(_module->getContext())); - } - else - { - throw GenericError("Unable to create bitcast to floating point type."); - } - - ret = irb.CreateFPCast(from, to); - } - break; - } - case eOpConv::SITOFP_OR_FPCAST: - { - if (!to->isFloatingPointTy()) - { - throw GenericError("Invalid combination of conversion method and destination type"); - } - if (from->getType()->isFloatingPointTy()) - { - ret = irb.CreateFPCast(from, to); - } - else - { - ret = irb.CreateSIToFP(from, to); - } - break; - } - case eOpConv::UITOFP_OR_FPCAST: - { - if (!to->isFloatingPointTy()) - { - throw GenericError("Invalid combination of conversion method and destination type"); - } - if (from->getType()->isFloatingPointTy()) - { - ret = irb.CreateFPCast(from, to); - } - else - { - ret = irb.CreateUIToFP(from, to); - } - break; - } - case eOpConv::NOTHING: - { - ret = from; - break; - } - case eOpConv::THROW: - default: - { - throw GenericError("Unhandled eOpConv type."); - } - } - - return ret; -} - -template -llvm::Type* Capstone2LlvmIrTranslator_impl::_checkTypeConversion( - llvm::IRBuilder<>& irb, - llvm::Type* to, - eOpConv ct) -{ - switch (ct) - { - case eOpConv::ZEXT_TRUNC_OR_BITCAST: - case eOpConv::SEXT_TRUNC_OR_BITCAST: - { - if (!to->isIntegerTy()) - { - auto size = _module->getDataLayout().getTypeStoreSizeInBits(to); - return irb.getIntNTy(size); - } - break; - } - case eOpConv::FPCAST_OR_BITCAST: - case eOpConv::SITOFP_OR_FPCAST: - case eOpConv::UITOFP_OR_FPCAST: - { - if (!to->isFloatingPointTy()) - { - auto flSize = _module->getDataLayout().getTypeStoreSizeInBits( - irb.getFloatTy()); - auto size = _module->getDataLayout().getTypeStoreSizeInBits(to); - if (size <= flSize) - { - return irb.getFloatTy(); - } - - return irb.getDoubleTy(); - } - break; - } - default: - { - return to; - } - } - - return to; -} - -/** - * op0 = __asm_() - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0Fnc( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_UNARY(i, ci, irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - getDefaultType(), - llvm::ArrayRef{}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * __asm_(op0) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_UNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - irb.getVoidTy(), - llvm::ArrayRef{op0->getType()}); - - irb.CreateCall(fnc, llvm::ArrayRef{op0}); -} - -/** - * op0 = __asm_(op0) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_UNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - op0->getType(), - llvm::ArrayRef{op0->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * __asm_(op0, op1) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0Op1( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_BINARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - irb.getVoidTy(), - llvm::ArrayRef{op0->getType(), op1->getType()}); - - irb.CreateCall(fnc, llvm::ArrayRef{op0, op1}); -} - -/** - * op0 = __asm_(op1) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp1( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_BINARY(i, ci, irb); - - op1 = loadOp(ci->operands[1], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - op1->getType(), - llvm::ArrayRef{op1->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op1}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * op0 = __asm_(op0, op1) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0Op1( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_BINARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - op0->getType(), - llvm::ArrayRef{op0->getType(), op1->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * __asm_(op0, op1, op2) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0Op1Op2( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_TERNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - irb.getVoidTy(), - llvm::ArrayRef{ - op0->getType(), - op1->getType(), - op2->getType()}); - - irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2}); -} - -/** - * op0 = __asm_(op1, op2) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp1Op2( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_TERNARY(i, ci, irb); - - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - getDefaultType(), - llvm::ArrayRef{ - op1->getType(), - op2->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op1, op2}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * op0 = __asm_(op0, op1, op2) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0Op1Op2( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_TERNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - op0->getType(), - llvm::ArrayRef{ - op0->getType(), - op1->getType(), - op2->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * __asm_(op0, op1, op2, op3) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0Op1Op2Op3( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_QUATERNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - op3 = loadOp(ci->operands[3], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - irb.getVoidTy(), - llvm::ArrayRef{ - op0->getType(), - op1->getType(), - op2->getType(), - op3->getType()}); - - irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2, op3}); -} - -/** - * op0 = __asm_(op1, op2, op3) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp1Op2Op3( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_QUATERNARY(i, ci, irb); - - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - op3 = loadOp(ci->operands[3], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - getDefaultType(), - llvm::ArrayRef{ - op1->getType(), - op2->getType(), - op3->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op1, op2, op3}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * op0 = __asm_(op0, op1, op2, op3) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0Op1Op2Op3( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_QUATERNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - op3 = loadOp(ci->operands[3], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - op0->getType(), - llvm::ArrayRef{ - op0->getType(), - op1->getType(), - op2->getType(), - op3->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2, op3}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * op0, op1 = __asm_(op0, op1, op2, op3) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0Op1FncOp0Op1Op2Op3( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_QUATERNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - op3 = loadOp(ci->operands[3], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - llvm::StructType::create(llvm::ArrayRef{ - op0->getType(), - op1->getType()}), - llvm::ArrayRef{ - op0->getType(), - op1->getType(), - op2->getType(), - op3->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2, op3}); - - storeOp(ci->operands[0], irb.CreateExtractValue(c, {0}), irb); - storeOp(ci->operands[1], irb.CreateExtractValue(c, {1}), irb); -} - -/** - * Some architectures do not have this info in operands. - * Return default value: CS_AC_INVALID. - */ -template -uint8_t Capstone2LlvmIrTranslator_impl::getOperandAccess(CInsnOp&) -{ - return CS_AC_INVALID; -} - -/** - * Generate pseudo asm call using information provided by Capstone. - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmGeneric( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - std::vector vals; - std::vector types; - - unsigned writeCnt = 0; - llvm::Type* writeType = getDefaultType(); - bool writesOp = false; - for (std::size_t j = 0; j < ci->op_count; ++j) - { - auto& op = ci->operands[j]; - auto access = getOperandAccess(op); - if (access == CS_AC_INVALID || (access & CS_AC_READ)) - { - auto* o = loadOp(op, irb); - vals.push_back(o); - types.push_back(o->getType()); - } - - if (access & CS_AC_WRITE) - { - writesOp = true; - ++writeCnt; - - if (isOperandRegister(op)) - { - auto* t = getRegisterType(op.reg); - if (writeCnt == 1 || writeType == t) - { - writeType = t; - } - else - { - writeType = getDefaultType(); - } - } - else - { - writeType = getDefaultType(); - } - } - } - - if (vals.empty()) - { - // All registers must be ok, or don't use them at all. - std::vector readRegs; - readRegs.reserve(i->detail->regs_read_count); - for (std::size_t j = 0; j < i->detail->regs_read_count; ++j) - { - auto r = i->detail->regs_read[j]; - if (getRegister(r)) - { - readRegs.push_back(r); - } - else - { - readRegs.clear(); - break; - } - } - - for (auto r : readRegs) - { - auto* op = loadRegister(r, irb); - vals.push_back(op); - types.push_back(op->getType()); - } - } - - auto* retType = writesOp ? writeType : irb.getVoidTy(); - llvm::Function* fnc = getPseudoAsmFunction( - i, - retType, - types); - - auto* c = irb.CreateCall(fnc, vals); - - std::set writtenRegs; - if (retType) - { - for (std::size_t j = 0; j < ci->op_count; ++j) - { - auto& op = ci->operands[j]; - if (getOperandAccess(op) & CS_AC_WRITE) - { - storeOp(op, c, irb); - - if (isOperandRegister(op)) - { - writtenRegs.insert(op.reg); - } - } - } - } - - // All registers must be ok, or don't use them at all. - std::vector writeRegs; - writeRegs.reserve(i->detail->regs_write_count); - for (std::size_t j = 0; j < i->detail->regs_write_count; ++j) - { - auto r = i->detail->regs_write[j]; - if (writtenRegs.count(r)) - { - // silently ignore - } - else if (getRegister(r)) - { - writeRegs.push_back(r); - } - else - { - writeRegs.clear(); - break; - } - } - - for (auto r : writeRegs) - { - llvm::Value* val = retType->isVoidTy() - ? llvm::cast( - llvm::UndefValue::get(getRegisterType(r))) - : llvm::cast(c); - storeRegister(r, val, irb); - } -} - -template -void Capstone2LlvmIrTranslator_impl::throwUnexpectedOperands( - cs_insn* i, - const std::string comment) -{ - if (!isIgnoreUnexpectedOperands()) - { - throw UnexpectedOperandsError(i, comment); - } -} - -template -void Capstone2LlvmIrTranslator_impl::throwUnhandledInstructions( - cs_insn* i, - const std::string comment) -{ - if (!isIgnoreUnhandledInstructions()) - { - throw UnhandledInstructionError(i, comment); - } -} - -template class Capstone2LlvmIrTranslator_impl; -template class Capstone2LlvmIrTranslator_impl; -template class Capstone2LlvmIrTranslator_impl; -template class Capstone2LlvmIrTranslator_impl; -template class Capstone2LlvmIrTranslator_impl; - -} // namespace capstone2llvmir -} // namespace retdec +/** + * @file src/capstone2llvmir/capstone2llvmir.cpp + * @brief Converts bytes to Capstone representation, and Capstone representation + * to LLVM IR. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#include + +#include "capstone2llvmir/capstone2llvmir_impl.h" + +namespace retdec { +namespace capstone2llvmir { + +template +Capstone2LlvmIrTranslator_impl::Capstone2LlvmIrTranslator_impl( + cs_arch a, + cs_mode basic, + cs_mode extra, + llvm::Module* m) + : + _arch(a), + _basicMode(basic), + _extraMode(extra), + _origBasicMode(basic), + _module(m) +{ + // Do not call anything here, especially virtual methods. +} + +template +Capstone2LlvmIrTranslator_impl::~Capstone2LlvmIrTranslator_impl() +{ + closeHandle(); +} + +// +//============================================================================== +// Translator configuration methods. +//============================================================================== +// + +template +void Capstone2LlvmIrTranslator_impl::setIgnoreUnexpectedOperands(bool f) +{ + _ignoreUnexpectedOperands = f; +} + +template +void Capstone2LlvmIrTranslator_impl::setIgnoreUnhandledInstructions(bool f) +{ + _ignoreUnhandledInstructions = f; +} + +template +void Capstone2LlvmIrTranslator_impl::setGeneratePseudoAsmFunctions(bool f) +{ + _generatePseudoAsmFunctions = f; +} + +template +bool Capstone2LlvmIrTranslator_impl::isIgnoreUnexpectedOperands() const +{ + return _ignoreUnexpectedOperands; +} + +template +bool Capstone2LlvmIrTranslator_impl::isIgnoreUnhandledInstructions() const +{ + return _ignoreUnhandledInstructions; +} + +template +bool Capstone2LlvmIrTranslator_impl::isGeneratePseudoAsmFunctions() const +{ + return _generatePseudoAsmFunctions; +} + +// +//============================================================================== +// Mode query & modification methods - from Capstone2LlvmIrTranslator. +//============================================================================== +// + +template +void Capstone2LlvmIrTranslator_impl::modifyBasicMode(cs_mode m) +{ + if (!isAllowedBasicMode(m)) + { + throw ModeSettingError( + _arch, + m, + ModeSettingError::eType::BASIC_MODE); + } + + if (cs_option(_handle, CS_OPT_MODE, m + _extraMode) != CS_ERR_OK) + { + throw CapstoneError(cs_errno(_handle)); + } + + _basicMode = m; +} + +template +void Capstone2LlvmIrTranslator_impl::modifyExtraMode(cs_mode m) +{ + if (!isAllowedExtraMode(m)) + { + throw ModeSettingError( + _arch, + m, + ModeSettingError::eType::EXTRA_MODE); + } + + if (cs_option(_handle, CS_OPT_MODE, m + _basicMode) != CS_ERR_OK) + { + throw CapstoneError(cs_errno(_handle)); + } + + _extraMode = m; +} + +template +uint32_t Capstone2LlvmIrTranslator_impl::getArchBitSize() +{ + return getArchByteSize() * 8; +} + +// +//============================================================================== +// Translation methods - from Capstone2LlvmIrTranslator. +//============================================================================== +// + +// TODO: Optimize -- to make generation easier and nicer, some things +// can be generated suboptimally. We should inspect every generated +// ASM insruction and optimize some known patterns: +// +// 1. Load propagation: +// a = load r +// ... use a, not change r, no fnc call, etc. +// b = load r +// ... use b -> replace by a, remove b +// +// 2. Conversions: +// a = cast b +// ... use a +// c = cast b +// ... use c -> replace by a, remove c +// +// 3. Unused values (e.g. from loadOpBinary() where only one op used): +// a = load x +// ... a unused +// +// 4. Values used only for their type (e.g. op0 load in translateMov()): +// a = load x +// b = load y +// c = convert b to a.type +// store c x +// +// etc. + +template +typename Capstone2LlvmIrTranslator_impl::TranslationResult +Capstone2LlvmIrTranslator_impl::translate( + const uint8_t* bytes, + std::size_t size, + retdec::common::Address a, + llvm::IRBuilder<>& irb, + std::size_t count, + bool stopOnBranch) +{ + TranslationResult res; + + // We want to keep all Capstone instructions -> alloc a new one each time. + cs_insn* insn = cs_malloc(_handle); + + uint64_t address = a; + + _branchGenerated = nullptr; + _inCondition = false; + + // TODO: hack, solve better. + bool disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); + if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) + { + modifyBasicMode(CS_MODE_MIPS64); + disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); + modifyBasicMode(CS_MODE_MIPS32); + } + + while (disasmRes) + { + auto* a2l = generateSpecialAsm2LlvmInstr(irb, insn); + + res.insns.push_back(std::make_pair(a2l, insn)); + res.size = (insn->address + insn->size) - a; + + translateInstruction(insn, irb); + + ++res.count; + if (count && count == res.count) + { + return res; + } + + if (_branchGenerated && stopOnBranch) + { + res.branchCall = _branchGenerated; + res.inCondition = _inCondition; + return res; + } + + insn = cs_malloc(_handle); + + // TODO: hack, solve better. + disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); + if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) + { + modifyBasicMode(CS_MODE_MIPS64); + disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); + modifyBasicMode(CS_MODE_MIPS32); + } + } + cs_free(insn, 1); + return res; +} + +template +typename Capstone2LlvmIrTranslator_impl::TranslationResultOne +Capstone2LlvmIrTranslator_impl::translateOne( + const uint8_t*& bytes, + std::size_t& size, + retdec::common::Address& a, + llvm::IRBuilder<>& irb) +{ + std::vector MPX_INSTRS{ + X86_INS_BNDMK, X86_INS_BNDCL, X86_INS_BNDCU, X86_INS_BNDMOV, X86_INS_BNDLDX, X86_INS_BNDSTX}; + bool MpxInstr = false; + TranslationResultOne res; + + // We want to keep all Capstone instructions -> alloc a new one each time. + cs_insn* insn = cs_malloc(_handle); + + uint64_t address = a; + _branchGenerated = nullptr; + _inCondition = false; + + // TODO: hack, solve better. + bool disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); + + for (auto& MpxIndexer : MPX_INSTRS) + { + if (insn[0].id == MpxIndexer) + MpxInstr = true; + } + + if (MpxInstr != true) + { + if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) + { + modifyBasicMode(CS_MODE_MIPS64); + disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); + modifyBasicMode(CS_MODE_MIPS32); + } + + if (disasmRes) + { + auto* a2l = generateSpecialAsm2LlvmInstr(irb, insn); + translateInstruction(insn, irb); + + res.llvmInsn = a2l; + res.capstoneInsn = insn; + res.size = insn->size; + res.branchCall = _branchGenerated; + res.inCondition = _inCondition; + + a = address; + } + else + { + cs_free(insn, 1); + } + } + else + { + auto* a2l = generateSpecialAsm2LlvmInstr(irb, insn); + + res.llvmInsn = a2l; + res.capstoneInsn = insn; + res.size = insn->size; + res.branchCall = _branchGenerated; + res.inCondition = _inCondition; + + a = address; + + return res; + } + return res; +} + +// +//============================================================================== +// Capstone related getters - from Capstone2LlvmIrTranslator. +//============================================================================== +// + +template +const csh& Capstone2LlvmIrTranslator_impl::getCapstoneEngine() const +{ + return _handle; +} + +template +cs_arch Capstone2LlvmIrTranslator_impl::getArchitecture() const +{ + return _arch; +} + +template +cs_mode Capstone2LlvmIrTranslator_impl::getBasicMode() const +{ + return _basicMode; +} + +template +cs_mode Capstone2LlvmIrTranslator_impl::getExtraMode() const +{ + return _extraMode; +} + +template +bool Capstone2LlvmIrTranslator_impl::hasDelaySlot(uint32_t id) const +{ + return false; +} + +template +bool Capstone2LlvmIrTranslator_impl::hasDelaySlotTypical(uint32_t id) const +{ + return false; +} + +template +bool Capstone2LlvmIrTranslator_impl::hasDelaySlotLikely(uint32_t id) const +{ + return false; +} + +template +std::size_t Capstone2LlvmIrTranslator_impl::getDelaySlot(uint32_t id) const +{ + return 0; +} + +template +llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::getRegister(uint32_t r) +{ + auto fIt = _capstone2LlvmRegs.find(r); + return fIt != _capstone2LlvmRegs.end() ? fIt->second : nullptr; +} + +template +std::string Capstone2LlvmIrTranslator_impl::getRegisterName(uint32_t r) const +{ + auto fIt = _reg2name.find(r); + if (fIt == _reg2name.end()) + { + if (auto* n = cs_reg_name(_handle, r)) + { + return n; + } + else + { + throw GenericError( + "Missing name for register number: " + std::to_string(r)); + } + } + else + { + return fIt->second; + } +} + +template +uint32_t Capstone2LlvmIrTranslator_impl::getRegisterBitSize(uint32_t r) const +{ + auto* rt = getRegisterType(r); + if (auto* it = llvm::dyn_cast(rt)) + { + return it->getBitWidth(); + } + else if (rt->isHalfTy()) + { + return 16; + } + else if (rt->isFloatTy()) + { + return 32; + } + else if (rt->isDoubleTy()) + { + return 64; + } + else if (rt->isX86_FP80Ty()) + { + return 80; + } + else if (rt->isFP128Ty()) + { + return 128; + } + else + { + throw GenericError( + "Unhandled type of register number: " + std::to_string(r)); + } +} + +template +uint32_t Capstone2LlvmIrTranslator_impl::getRegisterByteSize( + uint32_t r) const +{ + return getRegisterBitSize(r) / 8; +} + +template +llvm::Type* Capstone2LlvmIrTranslator_impl::getRegisterType( + uint32_t r) const +{ + auto fIt = _reg2type.find(r); + if (fIt == _reg2type.end()) + { + throw GenericError( + "Missing type for register number: " + std::to_string(r)); + } + return fIt->second; +} + +template +bool Capstone2LlvmIrTranslator_impl::isControlFlowInstruction( + cs_insn& i) const +{ + return _controlFlowInsnIds.count(i.id) + || isCallInstruction(i) + || isReturnInstruction(i) + || isBranchInstruction(i) + || isCondBranchInstruction(i); +} + +template +bool Capstone2LlvmIrTranslator_impl::isCallInstruction( + cs_insn& i) const +{ + return _callInsnIds.count(i.id); +} + +template +bool Capstone2LlvmIrTranslator_impl::isReturnInstruction( + cs_insn& i) const +{ + return _returnInsnIds.count(i.id); +} + +template +bool Capstone2LlvmIrTranslator_impl::isBranchInstruction( + cs_insn& i) const +{ + return _branchInsnIds.count(i.id); +} + +template +bool Capstone2LlvmIrTranslator_impl::isCondBranchInstruction( + cs_insn& i) const +{ + return _condBranchInsnIds.count(i.id); +} + +// +//============================================================================== +// LLVM related getters and query methods. +//============================================================================== +// + +template +llvm::BranchInst* +Capstone2LlvmIrTranslator_impl::getCondBranchForInsnInIfThen( + llvm::Instruction* i) const +{ + // Asm to LLVM mapping instruction is not in BB where call is. + auto* prev = i->getPrevNode(); + while (prev) + { + if (isSpecialAsm2LlvmInstr(prev)) + { + return nullptr; + } + prev = prev->getPrevNode(); + } + + auto* prevBb = i->getParent()->getPrevNode(); + auto* term = prevBb ? prevBb->getTerminator() : nullptr; + auto* br = llvm::dyn_cast_or_null(term); + if (prevBb == nullptr + || br == nullptr + || !br->isConditional() + || br->getSuccessor(0) != i->getParent()) + { + return nullptr; + } + + return br; +} + +template +llvm::Module* Capstone2LlvmIrTranslator_impl::getModule() const +{ + return _module; +} + +template +bool Capstone2LlvmIrTranslator_impl::isSpecialAsm2LlvmMapGlobal( + llvm::Value* v) const +{ + return _asm2llvmGv == v; +} + +template +llvm::StoreInst* Capstone2LlvmIrTranslator_impl::isSpecialAsm2LlvmInstr( + llvm::Value* v) const +{ + if (auto* s = llvm::dyn_cast(v)) + { + if (isSpecialAsm2LlvmMapGlobal(s->getPointerOperand())) + { + return s; + } + } + return nullptr; +} + +template +llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::getAsm2LlvmMapGlobalVariable() const +{ + return _asm2llvmGv; +} + +template +bool Capstone2LlvmIrTranslator_impl::isCallFunction(llvm::Function* f) const +{ + return f == _callFunction; +} + +template +bool Capstone2LlvmIrTranslator_impl::isCallFunctionCall(llvm::CallInst* c) const +{ + return c ? isCallFunction(c->getCalledFunction()) : false; +} + +template +llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionCallFunctionCall(llvm::CallInst* c) const +{ + return isCallFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; +} + +template +llvm::Function* Capstone2LlvmIrTranslator_impl::getCallFunction() const +{ + return _callFunction; +} + +template +bool Capstone2LlvmIrTranslator_impl::isReturnFunction(llvm::Function* f) const +{ + return f == _returnFunction; +} + +template +bool Capstone2LlvmIrTranslator_impl::isReturnFunctionCall( + llvm::CallInst* c) const +{ + return c ? isReturnFunction(c->getCalledFunction()) : false; +} + +template +llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionReturnFunctionCall(llvm::CallInst* c) const +{ + return isReturnFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; +} + +template +llvm::Function* Capstone2LlvmIrTranslator_impl::getReturnFunction() const +{ + return _returnFunction; +} + +template +bool Capstone2LlvmIrTranslator_impl::isBranchFunction(llvm::Function* f) const +{ + return _branchFunction == f; +} + +template +bool Capstone2LlvmIrTranslator_impl::isBranchFunctionCall( + llvm::CallInst* c) const +{ + return c ? isBranchFunction(c->getCalledFunction()) : false; +} + +template +llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionBranchFunctionCall(llvm::CallInst* c) const +{ + return isBranchFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; +} + +template +llvm::Function* Capstone2LlvmIrTranslator_impl::getBranchFunction() const +{ + return _branchFunction; +} + +template +bool Capstone2LlvmIrTranslator_impl::isCondBranchFunction( + llvm::Function* f) const +{ + return _condBranchFunction == f; +} + +template +bool Capstone2LlvmIrTranslator_impl::isCondBranchFunctionCall( + llvm::CallInst* c) const +{ + return c ? isCondBranchFunction(c->getCalledFunction()) : false; +} + +template +llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionCondBranchFunctionCall( + llvm::CallInst* c) const +{ + return isCondBranchFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; +} + +template +llvm::Function* Capstone2LlvmIrTranslator_impl::getCondBranchFunction() const +{ + return _condBranchFunction; +} + +template +bool Capstone2LlvmIrTranslator_impl::isAnyPseudoFunction( + llvm::Function* f) const +{ + return isCallFunction(f) + || isReturnFunction(f) + || isBranchFunction(f) + || isCondBranchFunction(f); +} + +template +bool Capstone2LlvmIrTranslator_impl::isAnyPseudoFunctionCall( + llvm::CallInst* c) const +{ + return isCallFunctionCall(c) + || isReturnFunctionCall(c) + || isBranchFunctionCall(c) + || isCondBranchFunctionCall(c); +} + +template +llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::isRegister( + llvm::Value* v) const +{ + auto it = _llvm2CapstoneRegs.find(llvm::dyn_cast_or_null(v)); + return it != _llvm2CapstoneRegs.end() ? it->first : nullptr; +} + +template +uint32_t Capstone2LlvmIrTranslator_impl::getCapstoneRegister( + llvm::GlobalVariable* gv) const +{ + auto it = _llvm2CapstoneRegs.find(gv); + return it != _llvm2CapstoneRegs.end() ? it->second : 0; +} + +template +bool Capstone2LlvmIrTranslator_impl::isPseudoAsmFunction( + llvm::Function* f) const +{ + return _asmFunctions.count(f); +} + +template +bool Capstone2LlvmIrTranslator_impl::isPseudoAsmFunctionCall( + llvm::CallInst* c) const +{ + return c ? isPseudoAsmFunction(c->getCalledFunction()) : false; +} + +template +const std::set& Capstone2LlvmIrTranslator_impl::getPseudoAsmFunctions() const +{ + return _asmFunctions; +} + +// +//============================================================================== +// +//============================================================================== +// + +template +void Capstone2LlvmIrTranslator_impl::initialize() +{ + if (!isAllowedBasicMode(_basicMode)) + { + throw ModeSettingError( + _arch, + _basicMode, + ModeSettingError::eType::BASIC_MODE); + } + if (!isAllowedExtraMode(_extraMode)) + { + throw ModeSettingError( + _arch, + _extraMode, + ModeSettingError::eType::EXTRA_MODE); + } + + openHandle(); // Sets both _basicMode and _extraMode. + configureHandle(); + + initializeRegNameMap(); + initializeRegTypeMap(); + initializePseudoCallInstructionIDs(); + initializeArchSpecific(); + + generateEnvironment(); +} + +template +void Capstone2LlvmIrTranslator_impl::openHandle() +{ + cs_mode finalMode = static_cast(_basicMode + _extraMode); + if (cs_open(_arch, finalMode, &_handle) != CS_ERR_OK) + { + throw CapstoneError(cs_errno(_handle)); + } +} + +template +void Capstone2LlvmIrTranslator_impl::configureHandle() +{ + if (cs_option(_handle, CS_OPT_DETAIL, CS_OPT_ON) != CS_ERR_OK) + { + throw CapstoneError(cs_errno(_handle)); + } +} + +template +void Capstone2LlvmIrTranslator_impl::closeHandle() +{ + if (_handle != 0) + { + if (cs_close(&_handle) != CS_ERR_OK) + { + throw CapstoneError(cs_errno(_handle)); + } + } +} + +template +void Capstone2LlvmIrTranslator_impl::generateEnvironment() +{ + generateSpecialAsm2LlvmMapGlobal(); + generateCallFunction(); + generateReturnFunction(); + generateBranchFunction(); + generateCondBranchFunction(); + + generateEnvironmentArchSpecific(); + generateRegisters(); + generateDataLayout(); +} + +/** + * The generated global variable is unnamed. capstone2llvmir library does not + * allow to specify or set its name. Users can however get the variable with + * @c getAsm2LlvmMapGlobalVariable() and do whatever they want with it + * (e.g. rename). + */ +template +void Capstone2LlvmIrTranslator_impl::generateSpecialAsm2LlvmMapGlobal() +{ + llvm::GlobalValue::LinkageTypes lt = llvm::GlobalValue::InternalLinkage; + llvm::Constant* initializer = nullptr; + auto* t = llvm::IntegerType::getInt64Ty(_module->getContext()); + if (initializer == nullptr + && lt != llvm::GlobalValue::LinkageTypes::ExternalLinkage) + { + initializer = llvm::ConstantInt::get(t, 0); + } + + _asm2llvmGv = new llvm::GlobalVariable( + *_module, + t, + false, // isConstant + lt, + initializer); +} + +template +llvm::StoreInst* Capstone2LlvmIrTranslator_impl::generateSpecialAsm2LlvmInstr( + llvm::IRBuilder<>& irb, + cs_insn* i) +{ + retdec::common::Address a = i->address; + auto* gv = getAsm2LlvmMapGlobalVariable(); + auto* ci = llvm::ConstantInt::get(gv->getValueType(), a, false); + auto* s = irb.CreateStore(ci, gv, true); + return s; +} + +template +void Capstone2LlvmIrTranslator_impl::generateCallFunction() +{ + auto* ft = llvm::FunctionType::get( + llvm::Type::getVoidTy(_module->getContext()), + {llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}, + false); + _callFunction = llvm::Function::Create( + ft, + llvm::GlobalValue::LinkageTypes::ExternalLinkage, + "", + _module); +} + +template +llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCallFunctionCall( + llvm::IRBuilder<>& irb, + llvm::Value* t) +{ + auto* a1t = _callFunction->arg_begin()->getType(); + t = irb.CreateSExtOrTrunc(t, a1t); + _branchGenerated = irb.CreateCall(_callFunction, {t}); + return _branchGenerated; +} + +template +llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCondCallFunctionCall( + llvm::IRBuilder<>& irb, + llvm::Value* cond, + llvm::Value* t) +{ + auto bodyIrb = generateIfThen(cond, irb); + + auto* a1t = _callFunction->arg_begin()->getType(); + t = bodyIrb.CreateSExtOrTrunc(t, a1t); + _branchGenerated = bodyIrb.CreateCall(_callFunction, {t}); + _inCondition = true; + return _branchGenerated; +} + +template +void Capstone2LlvmIrTranslator_impl::generateReturnFunction() +{ + auto* ft = llvm::FunctionType::get( + llvm::Type::getVoidTy(_module->getContext()), + {llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}, + false); + _returnFunction = llvm::Function::Create( + ft, + llvm::GlobalValue::LinkageTypes::ExternalLinkage, + "", + _module); +} + +template +llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateReturnFunctionCall( + llvm::IRBuilder<>& irb, + llvm::Value* t) +{ + auto* a1t = _returnFunction->arg_begin()->getType(); + t = irb.CreateSExtOrTrunc(t, a1t); + _branchGenerated = irb.CreateCall(_returnFunction, {t}); + return _branchGenerated; +} + +template +llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCondReturnFunctionCall( + llvm::IRBuilder<>& irb, + llvm::Value* cond, + llvm::Value* t) +{ + auto bodyIrb = generateIfThen(cond, irb); + + auto* a1t = _returnFunction->arg_begin()->getType(); + t = bodyIrb.CreateSExtOrTrunc(t, a1t); + _branchGenerated = bodyIrb.CreateCall(_returnFunction, {t}); + _inCondition = true; + return _branchGenerated; +} + +template +void Capstone2LlvmIrTranslator_impl::generateBranchFunction() +{ + auto* ft = llvm::FunctionType::get( + llvm::Type::getVoidTy(_module->getContext()), + {llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}, + false); + _branchFunction = llvm::Function::Create( + ft, + llvm::GlobalValue::LinkageTypes::ExternalLinkage, + "", + _module); +} + +template +llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateBranchFunctionCall( + llvm::IRBuilder<>& irb, + llvm::Value* t) +{ + auto* a1t = _branchFunction->arg_begin()->getType(); + t = irb.CreateSExtOrTrunc(t, a1t); + _branchGenerated = irb.CreateCall(_branchFunction, {t}); + return _branchGenerated; +} + +template +void Capstone2LlvmIrTranslator_impl::generateCondBranchFunction() +{ + std::vector params = { + llvm::Type::getInt1Ty(_module->getContext()), + llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}; + auto* ft = llvm::FunctionType::get( + llvm::Type::getVoidTy(_module->getContext()), + params, + false); + _condBranchFunction = llvm::Function::Create( + ft, + llvm::GlobalValue::LinkageTypes::ExternalLinkage, + "", + _module); +} + +template +llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCondBranchFunctionCall( + llvm::IRBuilder<>& irb, + llvm::Value* cond, + llvm::Value* t) +{ + auto aIt = _condBranchFunction->arg_begin(); + ++aIt; + auto* a1t = aIt->getType(); + t = irb.CreateSExtOrTrunc(t, a1t); + _branchGenerated = irb.CreateCall(_condBranchFunction, {cond, t}); + return _branchGenerated; +} + +template +llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::createRegister( + uint32_t r, + llvm::GlobalValue::LinkageTypes lt, + llvm::Constant* initializer) +{ + auto* rt = getRegisterType(r); + if (initializer == nullptr + && lt != llvm::GlobalValue::LinkageTypes::ExternalLinkage) + { + if (auto* it = llvm::dyn_cast(rt)) + { + initializer = llvm::ConstantInt::get(it, 0); + } + else if (rt->isFloatingPointTy()) + { + initializer = llvm::ConstantFP::get(rt, 0); + } + else + { + throw GenericError("Unhandled register type."); + } + } + + auto* gv = new llvm::GlobalVariable( + *_module, + rt, + false, // isConstant + lt, + initializer, + getRegisterName(r)); + + if (gv == nullptr) + { + throw GenericError("Memory allocation error."); + } + + _llvm2CapstoneRegs[gv] = r; + _capstone2LlvmRegs[r] = gv; + + return gv; +} + +// +//============================================================================== +// Load/store methods. +//============================================================================== +// + +template +llvm::Value* Capstone2LlvmIrTranslator_impl::loadOp( + CInsn* ci, + llvm::IRBuilder<>& irb, + std::size_t idx, + llvm::Type* loadType, + llvm::Type* dstType, + eOpConv ct) +{ + if (ci->op_count <= idx) + { + throw GenericError( + "Idx out of bounds: "+std::to_string(idx) + +"/"+std::to_string(ci->op_count)); + } + + auto* op = loadOp(ci->operands[idx], irb, loadType); + if (op == nullptr) + { + throw GenericError("Operand loading failed."); + } + + if (dstType == nullptr) + { + return op; + } + + return generateTypeConversion(irb, op, dstType, ct); +} + +template +std::vector Capstone2LlvmIrTranslator_impl::_loadOps( + CInsn* ci, + llvm::IRBuilder<>& irb, + std::size_t opCnt, + bool strict, + llvm::Type* loadType, + llvm::Type* dstType, + eOpConv ct) +{ + if ((strict && (ci->op_count != opCnt)) || (ci->op_count < opCnt)) + { + throw GenericError( + "Trying to load " + +std::to_string(opCnt) + +" operands from instruction with" + +std::to_string(ci->op_count) + +" opernads."); + } + + std::size_t startOp = ci->op_count - opCnt; + + std::vector operands; + + // If no destination type specified, use type of first operand. + if (dstType == nullptr) + { + auto* op0 = loadOp(ci, irb, startOp, loadType, dstType, ct); + dstType = op0->getType(); + dstType = _checkTypeConversion(irb, dstType, ct); + op0 = generateTypeConversion(irb, op0, dstType, ct); + startOp++; + operands.push_back(op0); + } + else + { + auto* type = _checkTypeConversion(irb, dstType, ct); + if (type != dstType) + { + throw GenericError( + "Invalid combination of destination type and conversion type."); + } + } + + for (; startOp < ci->op_count; startOp++) { + auto* op = loadOp(ci, irb, startOp, loadType, dstType, ct); + operands.push_back(op); + } + + return operands; +} + +template +std::vector +Capstone2LlvmIrTranslator_impl::_loadOpsUniversal( + CInsn* ci, + llvm::IRBuilder<>& irb, + std::size_t opCnt, + bool strict, + eOpConv ict, + eOpConv fct) +{ + if ((strict && (ci->op_count != opCnt)) || (ci->op_count < opCnt)) + { + throw GenericError( + "Trying to load " + +std::to_string(opCnt) + +" operands from instruction with" + +std::to_string(ci->op_count) + +" opernads."); + } + + auto op0 = loadOp(ci, irb, ci->op_count - opCnt); + if (op0->getType()->isIntegerTy()) + { + auto operands = _loadOps(ci, irb, opCnt-1, false, nullptr, op0->getType(), ict); + operands.insert(operands.begin(), op0); + return operands; + } + + auto operands = _loadOps(ci, irb, opCnt-1, false, nullptr, op0->getType(), fct); + operands.insert(operands.begin(), op0); + return operands; +} + +/** + * Throws if op_count != 1. + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::loadOpUnary( + CInsn* ci, + llvm::IRBuilder<>& irb, + llvm::Type* loadType, + llvm::Type* dstType, + eOpConv ct) +{ + return _loadOps(ci, irb, 1, true, loadType, dstType, ct)[0]; +} + +/** + * Throws if op_count != 2. + */ +template +std::pair +Capstone2LlvmIrTranslator_impl::loadOpBinary( + CInsn* ci, + llvm::IRBuilder<>& irb, + eOpConv ct) +{ + auto operands = _loadOps(ci, irb, 2, true, nullptr, nullptr, ct); + return std::make_pair(operands[0], operands[1]); +} + +/** + * Throws if op_count != 2. + */ +template +std::pair +Capstone2LlvmIrTranslator_impl::loadOpBinary( + CInsn* ci, + llvm::IRBuilder<>& irb, + eOpConv ict, + eOpConv fct) +{ + auto operands = _loadOpsUniversal(ci, irb, 2, true, ict, fct); + return std::make_pair(operands[0], operands[1]); +} + +template +std::pair +Capstone2LlvmIrTranslator_impl::loadOpBinary( + CInsn* ci, + llvm::IRBuilder<>& irb, + llvm::Type* loadType, + llvm::Type* dstType, + eOpConv ct) +{ + auto operands = _loadOps(ci, irb, 2, true, loadType, dstType, ct); + return std::make_pair(operands[0], operands[1]); +} + +/** + * Throws if op_count != 2. + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::loadOpBinaryOp0( + CInsn* ci, + llvm::IRBuilder<>& irb, + llvm::Type* ty) +{ + auto operand = loadOp(ci, irb, 0, ty); + return operand; +} + +/** + * Throws if op_count != 2. + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::loadOpBinaryOp1( + CInsn* ci, + llvm::IRBuilder<>& irb, + llvm::Type* ty) +{ + auto operand = loadOp(ci, irb, 1, ty); + return operand; +} + +/** + * Throws if op_count != 3. + */ +template +std::tuple +Capstone2LlvmIrTranslator_impl::loadOpTernary( + CInsn* ci, + llvm::IRBuilder<>& irb, + eOpConv ct) +{ + auto operands = _loadOps(ci, irb, 3, true, nullptr, nullptr, ct); + return std::make_tuple(operands[0], operands[1], operands[2]); +} + +/** + * Throws if op_count != 3. + */ +template +std::tuple +Capstone2LlvmIrTranslator_impl::loadOpTernary( + CInsn* ci, + llvm::IRBuilder<>& irb, + eOpConv ict, + eOpConv fct) +{ + auto operands = _loadOpsUniversal(ci, irb, 3, true, ict, fct); + return std::make_tuple(operands[0], operands[1], operands[2]); +} + +/** + * Throws if op_count != 3. + */ +template +std::tuple +Capstone2LlvmIrTranslator_impl::loadOpTernary( + CInsn* ci, + llvm::IRBuilder<>& irb, + llvm::Type* loadType, + llvm::Type* dstType, + eOpConv ct) +{ + auto operands = _loadOps(ci, irb, 3, true, loadType, dstType, ct); + return std::make_tuple(operands[0], operands[1], operands[2]); +} + +/** + * Throws if op_count not in {2, 3}. + */ +template +std::pair +Capstone2LlvmIrTranslator_impl::loadOpBinaryOrTernaryOp1Op2( + CInsn* ci, + llvm::IRBuilder<>& irb, + eOpConv ct) +{ + auto operands = _loadOps(ci, irb, 2, false, nullptr, nullptr, ct); + return std::make_pair(operands[0], operands[1]); +} + +/** + * Throws if op_count not in {2, 3}. + */ +template +std::pair +Capstone2LlvmIrTranslator_impl::loadOpBinaryOrTernaryOp1Op2( + CInsn* ci, + llvm::IRBuilder<>& irb, + eOpConv ict, + eOpConv fct) +{ + auto operands = _loadOpsUniversal(ci, irb, 2, false, ict, fct); + return std::make_pair(operands[0], operands[1]); +} + +/** + * Throws if op_count != 4. + */ +template +std::tuple +Capstone2LlvmIrTranslator_impl::loadOpQuaternaryOp1Op2Op3( + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + auto operands = _loadOps(ci, irb, 3, false); + return std::make_tuple(operands[0], operands[1], operands[2]); +} + +// +//============================================================================== +// Carry/overflow/borrow add/sub generation routines. +//============================================================================== +// + +/** + * carry_add() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAdd( + llvm::Value* add, + llvm::Value* op0, + llvm::IRBuilder<>& irb) +{ + return irb.CreateICmpULT(add, op0); +} + +/** + * carry_add_c() + * + * If @p cf is not passed, default cf register is used. Why pass it? + * - Pass cf if you want to generate nicer code - prevent second cf load if + * it is already loaded by caller. This should however be taken care of by + * after generation optimizations. + * - Use a different value as cf. + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAddC( + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb, + llvm::Value* cf) +{ + auto* add1 = irb.CreateAdd(op0, op1); + if (cf == nullptr) + { + cf = loadRegister(getCarryRegister(), irb); + } + auto* cfc = irb.CreateZExtOrTrunc(cf, add1->getType()); + auto* add2 = irb.CreateAdd(add1, cfc); + auto* icmp1 = irb.CreateICmpULE(add2, op0); + auto* icmp2 = irb.CreateICmpULT(add1, op0); + auto* cff = irb.CreateZExtOrTrunc(cf, irb.getInt1Ty()); + return irb.CreateSelect(cff, icmp1, icmp2); +} + +/** + * carry_add_int4() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAddInt4( + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb) +{ + auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); + auto* and0 = irb.CreateAnd(op0, ci15); + auto* and1 = irb.CreateAnd(op1, ci15); + auto* add = irb.CreateAdd(and0, and1); + return irb.CreateICmpUGT(add, ci15); +} + +/** + * carry_add_c_int4() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAddCInt4( + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb, + llvm::Value* cf) +{ + auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); + auto* and0 = irb.CreateAnd(op0, ci15); + auto* and1 = irb.CreateAnd(op1, ci15); + auto* a = irb.CreateAdd(and0, and1); + if (cf == nullptr) + { + cf = loadRegister( + getCarryRegister(), + irb, + a->getType(), + eOpConv::ZEXT_TRUNC_OR_BITCAST); + } + auto* cfc = irb.CreateZExtOrTrunc(cf, a->getType()); + auto* add = irb.CreateAdd(a, cfc); + return irb.CreateICmpUGT(add, ci15); +} + +/** + * overflow_add() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowAdd( + llvm::Value* add, + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb) +{ + auto* xor0 = irb.CreateXor(op0, add); + auto* xor1 = irb.CreateXor(op1, add); + auto* ofAnd = irb.CreateAnd(xor0, xor1); + return irb.CreateICmpSLT( + ofAnd, + llvm::ConstantInt::get(ofAnd->getType(), 0)); +} + +/** + * overflow_add_c() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowAddC( + llvm::Value* add, + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb, + llvm::Value* cf) +{ + if (cf == nullptr) + { + cf = loadRegister(getCarryRegister(), irb); + } + auto* cfc = irb.CreateZExtOrTrunc(cf, add->getType()); + auto* ofAdd = irb.CreateAdd(add, cfc); + auto* xor0 = irb.CreateXor(op0, ofAdd); + auto* xor1 = irb.CreateXor(op1, ofAdd); + auto* ofAnd = irb.CreateAnd(xor0, xor1); + return irb.CreateICmpSLT(ofAnd, llvm::ConstantInt::get(ofAnd->getType(), 0)); +} + +/** + * overflow_sub() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowSub( + llvm::Value* sub, + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb) +{ + auto* xor0 = irb.CreateXor(op0, op1); + auto* xor1 = irb.CreateXor(op0, sub); + auto* ofAnd = irb.CreateAnd(xor0, xor1); + return irb.CreateICmpSLT( + ofAnd, + llvm::ConstantInt::get(ofAnd->getType(), 0)); +} + +/** + * overflow_sub_c() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowSubC( + llvm::Value* sub, + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb, + llvm::Value* cf) +{ + if (cf == nullptr) + { + cf = loadRegister(getCarryRegister(), irb); + } + auto* cfc = irb.CreateZExtOrTrunc(cf, sub->getType()); + auto* ofSub = irb.CreateSub(sub, cfc); + auto* xor0 = irb.CreateXor(op0, op1); + auto* xor1 = irb.CreateXor(op0, ofSub); + auto* ofAnd = irb.CreateAnd(xor0, xor1); + return irb.CreateICmpSLT( + ofAnd, + llvm::ConstantInt::get(ofAnd->getType(), 0)); +} + +/** + * borrow_sub() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSub( + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb) +{ + return irb.CreateICmpULT(op0, op1); +} + +/** + * borrow_sub_c() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSubC( + llvm::Value* sub, + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb, + llvm::Value* cf) +{ + if (cf == nullptr) + { + cf = loadRegister(getCarryRegister(), irb); + } + auto* cfc = irb.CreateZExtOrTrunc(cf, sub->getType()); + auto* cfSub = irb.CreateSub(sub, cfc); + auto* cfIcmp1 = irb.CreateICmpULT(op0, cfSub); + auto* negOne = llvm::ConstantInt::getSigned(op1->getType(), -1); + auto* cfIcmp2 = irb.CreateICmpULT(op1, negOne); + auto* cfOr = irb.CreateOr(cfIcmp1, cfIcmp2); + auto* cfIcmp3 = irb.CreateICmpULT(op0, op1); + auto* cff = irb.CreateZExtOrTrunc(cf, irb.getInt1Ty()); + return irb.CreateSelect(cff, cfOr, cfIcmp3); +} + +/** + * borrow_sub_int4() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSubInt4( + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb) +{ + auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); + auto* and0 = irb.CreateAnd(op0, ci15); + auto* and1 = irb.CreateAnd(op1, ci15); + auto* afSub = irb.CreateSub(and0, and1); + return irb.CreateICmpUGT(afSub, ci15); +} + +/** + * borrow_sub_c_int4() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSubCInt4( + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb, + llvm::Value* cf) +{ + auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); + auto* and0 = irb.CreateAnd(op0, ci15); + auto* and1 = irb.CreateAnd(op1, ci15); + auto* sub = irb.CreateSub(and0, and1); + if (cf == nullptr) + { + cf = loadRegister(getCarryRegister(), irb); + } + auto* cfc = irb.CreateZExtOrTrunc(cf, sub->getType()); + auto* add = irb.CreateAdd(sub, cfc); + return irb.CreateICmpUGT(add, ci15); +} + +// +//============================================================================== +// Non-virtual helper methods. +//============================================================================== +// + +template +llvm::IntegerType* Capstone2LlvmIrTranslator_impl::getDefaultType() +{ + return getIntegerTypeFromByteSize(_module, getArchByteSize()); +} + +template +llvm::Value* Capstone2LlvmIrTranslator_impl::getThisInsnAddress( + cs_insn* i) +{ + return llvm::ConstantInt::get(getDefaultType(), i->address); +} + +template +llvm::Value* Capstone2LlvmIrTranslator_impl::getNextInsnAddress( + cs_insn* i) +{ + return llvm::ConstantInt::get(getDefaultType(), i->address + i->size); +} + +/** + * Generate pseudo assembly function name from the given instruction @a insn. + */ +template +std::string Capstone2LlvmIrTranslator_impl::getPseudoAsmFunctionName( + cs_insn* insn) +{ + return "__asm_" + std::string(insn->mnemonic); +} + +/** + * Get already existing asm functions associated with @p name, or if there + * is no such function, create it using @p name and @p type, add it to asm + * functions and return it. + * @return Functions associated with @p insnId. + */ +template +llvm::Function* Capstone2LlvmIrTranslator_impl::getPseudoAsmFunction( + cs_insn* insn, + llvm::FunctionType* type, + const std::string& name) +{ + auto n = name.empty() ? getPseudoAsmFunctionName(insn) : name; + auto p = std::make_pair(n, type); + auto fIt = _insn2asmFunctions.find(p); + if (fIt == _insn2asmFunctions.end()) + { + auto* fnc = llvm::Function::Create( + type, + llvm::GlobalValue::LinkageTypes::ExternalLinkage, + n, + _module); + _insn2asmFunctions[p] = fnc; + _asmFunctions.insert(fnc); + return fnc; + } + else + { + return fIt->second; + } +} + +/** + * The same as @c getPseudoAsmFunction(std::size_t,std::string&, llvm::FunctionType*), + * but function type is created by this variant. + */ +template +llvm::Function* Capstone2LlvmIrTranslator_impl::getPseudoAsmFunction( + cs_insn* insn, + llvm::Type* retType, + llvm::ArrayRef params, + const std::string& name) +{ + return getPseudoAsmFunction( + insn, + llvm::FunctionType::get(retType, params, false), + name); +} + +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateTypeConversion( + llvm::IRBuilder<>& irb, + llvm::Value* from, + llvm::Type* to, + eOpConv ct) +{ + if (to == nullptr || from->getType() == to) + { + return from; + } + + llvm::Value* ret = nullptr; + + switch (ct) + { + case eOpConv::SEXT_TRUNC_OR_BITCAST: + { + if (!to->isIntegerTy()) + { + throw GenericError("Invalid combination of conversion method and destination type"); + } + + if (from->getType()->isIntegerTy()) + { + ret = irb.CreateSExtOrTrunc(from, to); + } + else + { + auto size = _module->getDataLayout().getTypeStoreSizeInBits(from->getType()); + auto intTy = irb.getIntNTy(size); + ret = irb.CreateBitCast(from, intTy); + ret = irb.CreateZExtOrTrunc(ret, to); + } + break; + } + case eOpConv::ZEXT_TRUNC_OR_BITCAST: + { + if (!to->isIntegerTy()) + { + throw GenericError("Invalid combination of conversion method and destination type"); + } + + if (from->getType()->isIntegerTy()) + { + ret = irb.CreateZExtOrTrunc(from, to); + } + else + { + auto size = _module->getDataLayout().getTypeStoreSizeInBits(from->getType()); + auto intTy = irb.getIntNTy(size); + ret = irb.CreateBitCast(from, intTy); + ret = irb.CreateZExtOrTrunc(ret, to); + } + break; + } + case eOpConv::FPCAST_OR_BITCAST: + { + if (!to->isFloatingPointTy()) + { + throw GenericError("Invalid combination of conversion method and destination type"); + } + + if (from->getType()->isFloatingPointTy()) + { + ret = irb.CreateFPCast(from, to); + } + else + { + auto isize = _module->getDataLayout().getTypeStoreSizeInBits(from->getType()); + auto dsize = _module->getDataLayout().getTypeStoreSizeInBits(irb.getDoubleTy()); + auto fsize = _module->getDataLayout().getTypeStoreSizeInBits(irb.getFloatTy()); + auto lsize = _module->getDataLayout().getTypeStoreSizeInBits(llvm::Type::getFP128Ty(_module->getContext())); + + if (isize == fsize) + { + from = irb.CreateBitCast(from, irb.getFloatTy()); + } + else if (isize == dsize) + { + from = irb.CreateBitCast(from, irb.getDoubleTy()); + } + else if (isize == lsize) + { + from = irb.CreateBitCast(from, llvm::Type::getFP128Ty(_module->getContext())); + } + else + { + throw GenericError("Unable to create bitcast to floating point type."); + } + + ret = irb.CreateFPCast(from, to); + } + break; + } + case eOpConv::SITOFP_OR_FPCAST: + { + if (!to->isFloatingPointTy()) + { + throw GenericError("Invalid combination of conversion method and destination type"); + } + if (from->getType()->isFloatingPointTy()) + { + ret = irb.CreateFPCast(from, to); + } + else + { + ret = irb.CreateSIToFP(from, to); + } + break; + } + case eOpConv::UITOFP_OR_FPCAST: + { + if (!to->isFloatingPointTy()) + { + throw GenericError("Invalid combination of conversion method and destination type"); + } + if (from->getType()->isFloatingPointTy()) + { + ret = irb.CreateFPCast(from, to); + } + else + { + ret = irb.CreateUIToFP(from, to); + } + break; + } + case eOpConv::NOTHING: + { + ret = from; + break; + } + case eOpConv::THROW: + default: + { + throw GenericError("Unhandled eOpConv type."); + } + } + + return ret; +} + +template +llvm::Type* Capstone2LlvmIrTranslator_impl::_checkTypeConversion( + llvm::IRBuilder<>& irb, + llvm::Type* to, + eOpConv ct) +{ + switch (ct) + { + case eOpConv::ZEXT_TRUNC_OR_BITCAST: + case eOpConv::SEXT_TRUNC_OR_BITCAST: + { + if (!to->isIntegerTy()) + { + auto size = _module->getDataLayout().getTypeStoreSizeInBits(to); + return irb.getIntNTy(size); + } + break; + } + case eOpConv::FPCAST_OR_BITCAST: + case eOpConv::SITOFP_OR_FPCAST: + case eOpConv::UITOFP_OR_FPCAST: + { + if (!to->isFloatingPointTy()) + { + auto flSize = _module->getDataLayout().getTypeStoreSizeInBits( + irb.getFloatTy()); + auto size = _module->getDataLayout().getTypeStoreSizeInBits(to); + if (size <= flSize) + { + return irb.getFloatTy(); + } + + return irb.getDoubleTy(); + } + break; + } + default: + { + return to; + } + } + + return to; +} + +/** + * op0 = __asm_() + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0Fnc( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_UNARY(i, ci, irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + getDefaultType(), + llvm::ArrayRef{}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * __asm_(op0) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_UNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + irb.getVoidTy(), + llvm::ArrayRef{op0->getType()}); + + irb.CreateCall(fnc, llvm::ArrayRef{op0}); +} + +/** + * op0 = __asm_(op0) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_UNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + op0->getType(), + llvm::ArrayRef{op0->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * __asm_(op0, op1) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0Op1( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_BINARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + irb.getVoidTy(), + llvm::ArrayRef{op0->getType(), op1->getType()}); + + irb.CreateCall(fnc, llvm::ArrayRef{op0, op1}); +} + +/** + * op0 = __asm_(op1) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp1( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_BINARY(i, ci, irb); + + op1 = loadOp(ci->operands[1], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + op1->getType(), + llvm::ArrayRef{op1->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op1}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * op0 = __asm_(op0, op1) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0Op1( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_BINARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + op0->getType(), + llvm::ArrayRef{op0->getType(), op1->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * __asm_(op0, op1, op2) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0Op1Op2( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_TERNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + irb.getVoidTy(), + llvm::ArrayRef{ + op0->getType(), + op1->getType(), + op2->getType()}); + + irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2}); +} + +/** + * op0 = __asm_(op1, op2) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp1Op2( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_TERNARY(i, ci, irb); + + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + getDefaultType(), + llvm::ArrayRef{ + op1->getType(), + op2->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op1, op2}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * op0 = __asm_(op0, op1, op2) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0Op1Op2( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_TERNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + op0->getType(), + llvm::ArrayRef{ + op0->getType(), + op1->getType(), + op2->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * __asm_(op0, op1, op2, op3) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0Op1Op2Op3( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_QUATERNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + op3 = loadOp(ci->operands[3], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + irb.getVoidTy(), + llvm::ArrayRef{ + op0->getType(), + op1->getType(), + op2->getType(), + op3->getType()}); + + irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2, op3}); +} + +/** + * op0 = __asm_(op1, op2, op3) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp1Op2Op3( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_QUATERNARY(i, ci, irb); + + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + op3 = loadOp(ci->operands[3], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + getDefaultType(), + llvm::ArrayRef{ + op1->getType(), + op2->getType(), + op3->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op1, op2, op3}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * op0 = __asm_(op0, op1, op2, op3) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0Op1Op2Op3( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_QUATERNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + op3 = loadOp(ci->operands[3], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + op0->getType(), + llvm::ArrayRef{ + op0->getType(), + op1->getType(), + op2->getType(), + op3->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2, op3}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * op0, op1 = __asm_(op0, op1, op2, op3) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0Op1FncOp0Op1Op2Op3( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_QUATERNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + op3 = loadOp(ci->operands[3], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + llvm::StructType::create(llvm::ArrayRef{ + op0->getType(), + op1->getType()}), + llvm::ArrayRef{ + op0->getType(), + op1->getType(), + op2->getType(), + op3->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2, op3}); + + storeOp(ci->operands[0], irb.CreateExtractValue(c, {0}), irb); + storeOp(ci->operands[1], irb.CreateExtractValue(c, {1}), irb); +} + +/** + * Some architectures do not have this info in operands. + * Return default value: CS_AC_INVALID. + */ +template +uint8_t Capstone2LlvmIrTranslator_impl::getOperandAccess(CInsnOp&) +{ + return CS_AC_INVALID; +} + +/** + * Generate pseudo asm call using information provided by Capstone. + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmGeneric( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + std::vector vals; + std::vector types; + + unsigned writeCnt = 0; + llvm::Type* writeType = getDefaultType(); + bool writesOp = false; + for (std::size_t j = 0; j < ci->op_count; ++j) + { + auto& op = ci->operands[j]; + auto access = getOperandAccess(op); + if (access == CS_AC_INVALID || (access & CS_AC_READ)) + { + auto* o = loadOp(op, irb); + vals.push_back(o); + types.push_back(o->getType()); + } + + if (access & CS_AC_WRITE) + { + writesOp = true; + ++writeCnt; + + if (isOperandRegister(op)) + { + auto* t = getRegisterType(op.reg); + if (writeCnt == 1 || writeType == t) + { + writeType = t; + } + else + { + writeType = getDefaultType(); + } + } + else + { + writeType = getDefaultType(); + } + } + } + + if (vals.empty()) + { + // All registers must be ok, or don't use them at all. + std::vector readRegs; + readRegs.reserve(i->detail->regs_read_count); + for (std::size_t j = 0; j < i->detail->regs_read_count; ++j) + { + auto r = i->detail->regs_read[j]; + if (getRegister(r)) + { + readRegs.push_back(r); + } + else + { + readRegs.clear(); + break; + } + } + + for (auto r : readRegs) + { + auto* op = loadRegister(r, irb); + vals.push_back(op); + types.push_back(op->getType()); + } + } + + auto* retType = writesOp ? writeType : irb.getVoidTy(); + llvm::Function* fnc = getPseudoAsmFunction( + i, + retType, + types); + + auto* c = irb.CreateCall(fnc, vals); + + std::set writtenRegs; + if (retType) + { + for (std::size_t j = 0; j < ci->op_count; ++j) + { + auto& op = ci->operands[j]; + if (getOperandAccess(op) & CS_AC_WRITE) + { + storeOp(op, c, irb); + + if (isOperandRegister(op)) + { + writtenRegs.insert(op.reg); + } + } + } + } + + // All registers must be ok, or don't use them at all. + std::vector writeRegs; + writeRegs.reserve(i->detail->regs_write_count); + for (std::size_t j = 0; j < i->detail->regs_write_count; ++j) + { + auto r = i->detail->regs_write[j]; + if (writtenRegs.count(r)) + { + // silently ignore + } + else if (getRegister(r)) + { + writeRegs.push_back(r); + } + else + { + writeRegs.clear(); + break; + } + } + + for (auto r : writeRegs) + { + llvm::Value* val = retType->isVoidTy() + ? llvm::cast( + llvm::UndefValue::get(getRegisterType(r))) + : llvm::cast(c); + storeRegister(r, val, irb); + } +} + +template +void Capstone2LlvmIrTranslator_impl::throwUnexpectedOperands( + cs_insn* i, + const std::string comment) +{ + if (!isIgnoreUnexpectedOperands()) + { + throw UnexpectedOperandsError(i, comment); + } +} + +template +void Capstone2LlvmIrTranslator_impl::throwUnhandledInstructions( + cs_insn* i, + const std::string comment) +{ + if (!isIgnoreUnhandledInstructions()) + { + throw UnhandledInstructionError(i, comment); + } +} + +template class Capstone2LlvmIrTranslator_impl; +template class Capstone2LlvmIrTranslator_impl; +template class Capstone2LlvmIrTranslator_impl; +template class Capstone2LlvmIrTranslator_impl; +template class Capstone2LlvmIrTranslator_impl; + +} // namespace capstone2llvmir +} // namespace retdec From 5654cead2cb98c8f1724b36043e9ed8ee1f555b0 Mon Sep 17 00:00:00 2001 From: Nitr0-G <120374383+Nitr0-G@users.noreply.github.com> Date: Thu, 27 Apr 2023 00:04:24 +0300 Subject: [PATCH 2/5] Intel MPX support Skipping all MPX instructions has been added in order to eliminate bugs caused on these Issues (https://github.com/avast/retdec/issues/1148 https://github.com/avast/retdec/issues/1135) Intel MPX is a dead technology that has not been supported by the Linux kernel since 2020(proof: https://www.phoronix.com/news/Intel-MPX-Is-Dead). It was only in the Skylake and Intel Goldmont(atom) architecture, consider all current processors do not support this technology. Zydis & capstone mistakenly disassembles instructions added to Intel MPX(Intel MPX adds 7 new instructions, as well as BND0-3 registers in x64 and x32 mode for more information, see here(https://intel-mpx.github.io/design/ )), a tool like Hiew also does not disassemble instructions of Intel MPX (https://fpic.in/VQ9yfJ1) --- src/capstone2llvmir/capstone2llvmir_impl.cpp | 4645 +++++++++--------- 1 file changed, 2324 insertions(+), 2321 deletions(-) diff --git a/src/capstone2llvmir/capstone2llvmir_impl.cpp b/src/capstone2llvmir/capstone2llvmir_impl.cpp index 09481ff36..0048acc8b 100644 --- a/src/capstone2llvmir/capstone2llvmir_impl.cpp +++ b/src/capstone2llvmir/capstone2llvmir_impl.cpp @@ -1,2321 +1,2324 @@ -/** - * @file src/capstone2llvmir/capstone2llvmir.cpp - * @brief Converts bytes to Capstone representation, and Capstone representation - * to LLVM IR. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include - -#include "capstone2llvmir/capstone2llvmir_impl.h" - -namespace retdec { -namespace capstone2llvmir { - -template -Capstone2LlvmIrTranslator_impl::Capstone2LlvmIrTranslator_impl( - cs_arch a, - cs_mode basic, - cs_mode extra, - llvm::Module* m) - : - _arch(a), - _basicMode(basic), - _extraMode(extra), - _origBasicMode(basic), - _module(m) -{ - // Do not call anything here, especially virtual methods. -} - -template -Capstone2LlvmIrTranslator_impl::~Capstone2LlvmIrTranslator_impl() -{ - closeHandle(); -} - -// -//============================================================================== -// Translator configuration methods. -//============================================================================== -// - -template -void Capstone2LlvmIrTranslator_impl::setIgnoreUnexpectedOperands(bool f) -{ - _ignoreUnexpectedOperands = f; -} - -template -void Capstone2LlvmIrTranslator_impl::setIgnoreUnhandledInstructions(bool f) -{ - _ignoreUnhandledInstructions = f; -} - -template -void Capstone2LlvmIrTranslator_impl::setGeneratePseudoAsmFunctions(bool f) -{ - _generatePseudoAsmFunctions = f; -} - -template -bool Capstone2LlvmIrTranslator_impl::isIgnoreUnexpectedOperands() const -{ - return _ignoreUnexpectedOperands; -} - -template -bool Capstone2LlvmIrTranslator_impl::isIgnoreUnhandledInstructions() const -{ - return _ignoreUnhandledInstructions; -} - -template -bool Capstone2LlvmIrTranslator_impl::isGeneratePseudoAsmFunctions() const -{ - return _generatePseudoAsmFunctions; -} - -// -//============================================================================== -// Mode query & modification methods - from Capstone2LlvmIrTranslator. -//============================================================================== -// - -template -void Capstone2LlvmIrTranslator_impl::modifyBasicMode(cs_mode m) -{ - if (!isAllowedBasicMode(m)) - { - throw ModeSettingError( - _arch, - m, - ModeSettingError::eType::BASIC_MODE); - } - - if (cs_option(_handle, CS_OPT_MODE, m + _extraMode) != CS_ERR_OK) - { - throw CapstoneError(cs_errno(_handle)); - } - - _basicMode = m; -} - -template -void Capstone2LlvmIrTranslator_impl::modifyExtraMode(cs_mode m) -{ - if (!isAllowedExtraMode(m)) - { - throw ModeSettingError( - _arch, - m, - ModeSettingError::eType::EXTRA_MODE); - } - - if (cs_option(_handle, CS_OPT_MODE, m + _basicMode) != CS_ERR_OK) - { - throw CapstoneError(cs_errno(_handle)); - } - - _extraMode = m; -} - -template -uint32_t Capstone2LlvmIrTranslator_impl::getArchBitSize() -{ - return getArchByteSize() * 8; -} - -// -//============================================================================== -// Translation methods - from Capstone2LlvmIrTranslator. -//============================================================================== -// - -// TODO: Optimize -- to make generation easier and nicer, some things -// can be generated suboptimally. We should inspect every generated -// ASM insruction and optimize some known patterns: -// -// 1. Load propagation: -// a = load r -// ... use a, not change r, no fnc call, etc. -// b = load r -// ... use b -> replace by a, remove b -// -// 2. Conversions: -// a = cast b -// ... use a -// c = cast b -// ... use c -> replace by a, remove c -// -// 3. Unused values (e.g. from loadOpBinary() where only one op used): -// a = load x -// ... a unused -// -// 4. Values used only for their type (e.g. op0 load in translateMov()): -// a = load x -// b = load y -// c = convert b to a.type -// store c x -// -// etc. - -template -typename Capstone2LlvmIrTranslator_impl::TranslationResult -Capstone2LlvmIrTranslator_impl::translate( - const uint8_t* bytes, - std::size_t size, - retdec::common::Address a, - llvm::IRBuilder<>& irb, - std::size_t count, - bool stopOnBranch) -{ - TranslationResult res; - - // We want to keep all Capstone instructions -> alloc a new one each time. - cs_insn* insn = cs_malloc(_handle); - - uint64_t address = a; - - _branchGenerated = nullptr; - _inCondition = false; - - // TODO: hack, solve better. - bool disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) - { - modifyBasicMode(CS_MODE_MIPS64); - disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - modifyBasicMode(CS_MODE_MIPS32); - } - - while (disasmRes) - { - auto* a2l = generateSpecialAsm2LlvmInstr(irb, insn); - - res.insns.push_back(std::make_pair(a2l, insn)); - res.size = (insn->address + insn->size) - a; - - translateInstruction(insn, irb); - - ++res.count; - if (count && count == res.count) - { - return res; - } - - if (_branchGenerated && stopOnBranch) - { - res.branchCall = _branchGenerated; - res.inCondition = _inCondition; - return res; - } - - insn = cs_malloc(_handle); - - // TODO: hack, solve better. - disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) - { - modifyBasicMode(CS_MODE_MIPS64); - disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - modifyBasicMode(CS_MODE_MIPS32); - } - } - cs_free(insn, 1); - return res; -} - -template -typename Capstone2LlvmIrTranslator_impl::TranslationResultOne -Capstone2LlvmIrTranslator_impl::translateOne( - const uint8_t*& bytes, - std::size_t& size, - retdec::common::Address& a, - llvm::IRBuilder<>& irb) -{ - std::vector MPX_INSTRS{ - X86_INS_BNDMK, X86_INS_BNDCL, X86_INS_BNDCU, X86_INS_BNDMOV, X86_INS_BNDLDX, X86_INS_BNDSTX}; - bool MpxInstr = false; - TranslationResultOne res; - - // We want to keep all Capstone instructions -> alloc a new one each time. - cs_insn* insn = cs_malloc(_handle); - - uint64_t address = a; - _branchGenerated = nullptr; - _inCondition = false; - - // TODO: hack, solve better. - bool disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - - for (auto& MpxIndexer : MPX_INSTRS) - { - if (insn[0].id == MpxIndexer) - MpxInstr = true; - } - - if (MpxInstr != true) - { - if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) - { - modifyBasicMode(CS_MODE_MIPS64); - disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - modifyBasicMode(CS_MODE_MIPS32); - } - - if (disasmRes) - { - auto* a2l = generateSpecialAsm2LlvmInstr(irb, insn); - translateInstruction(insn, irb); - - res.llvmInsn = a2l; - res.capstoneInsn = insn; - res.size = insn->size; - res.branchCall = _branchGenerated; - res.inCondition = _inCondition; - - a = address; - } - else - { - cs_free(insn, 1); - } - } - else - { - auto* a2l = generateSpecialAsm2LlvmInstr(irb, insn); - - res.llvmInsn = a2l; - res.capstoneInsn = insn; - res.size = insn->size; - res.branchCall = _branchGenerated; - res.inCondition = _inCondition; - - a = address; - - return res; - } - return res; -} - -// -//============================================================================== -// Capstone related getters - from Capstone2LlvmIrTranslator. -//============================================================================== -// - -template -const csh& Capstone2LlvmIrTranslator_impl::getCapstoneEngine() const -{ - return _handle; -} - -template -cs_arch Capstone2LlvmIrTranslator_impl::getArchitecture() const -{ - return _arch; -} - -template -cs_mode Capstone2LlvmIrTranslator_impl::getBasicMode() const -{ - return _basicMode; -} - -template -cs_mode Capstone2LlvmIrTranslator_impl::getExtraMode() const -{ - return _extraMode; -} - -template -bool Capstone2LlvmIrTranslator_impl::hasDelaySlot(uint32_t id) const -{ - return false; -} - -template -bool Capstone2LlvmIrTranslator_impl::hasDelaySlotTypical(uint32_t id) const -{ - return false; -} - -template -bool Capstone2LlvmIrTranslator_impl::hasDelaySlotLikely(uint32_t id) const -{ - return false; -} - -template -std::size_t Capstone2LlvmIrTranslator_impl::getDelaySlot(uint32_t id) const -{ - return 0; -} - -template -llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::getRegister(uint32_t r) -{ - auto fIt = _capstone2LlvmRegs.find(r); - return fIt != _capstone2LlvmRegs.end() ? fIt->second : nullptr; -} - -template -std::string Capstone2LlvmIrTranslator_impl::getRegisterName(uint32_t r) const -{ - auto fIt = _reg2name.find(r); - if (fIt == _reg2name.end()) - { - if (auto* n = cs_reg_name(_handle, r)) - { - return n; - } - else - { - throw GenericError( - "Missing name for register number: " + std::to_string(r)); - } - } - else - { - return fIt->second; - } -} - -template -uint32_t Capstone2LlvmIrTranslator_impl::getRegisterBitSize(uint32_t r) const -{ - auto* rt = getRegisterType(r); - if (auto* it = llvm::dyn_cast(rt)) - { - return it->getBitWidth(); - } - else if (rt->isHalfTy()) - { - return 16; - } - else if (rt->isFloatTy()) - { - return 32; - } - else if (rt->isDoubleTy()) - { - return 64; - } - else if (rt->isX86_FP80Ty()) - { - return 80; - } - else if (rt->isFP128Ty()) - { - return 128; - } - else - { - throw GenericError( - "Unhandled type of register number: " + std::to_string(r)); - } -} - -template -uint32_t Capstone2LlvmIrTranslator_impl::getRegisterByteSize( - uint32_t r) const -{ - return getRegisterBitSize(r) / 8; -} - -template -llvm::Type* Capstone2LlvmIrTranslator_impl::getRegisterType( - uint32_t r) const -{ - auto fIt = _reg2type.find(r); - if (fIt == _reg2type.end()) - { - throw GenericError( - "Missing type for register number: " + std::to_string(r)); - } - return fIt->second; -} - -template -bool Capstone2LlvmIrTranslator_impl::isControlFlowInstruction( - cs_insn& i) const -{ - return _controlFlowInsnIds.count(i.id) - || isCallInstruction(i) - || isReturnInstruction(i) - || isBranchInstruction(i) - || isCondBranchInstruction(i); -} - -template -bool Capstone2LlvmIrTranslator_impl::isCallInstruction( - cs_insn& i) const -{ - return _callInsnIds.count(i.id); -} - -template -bool Capstone2LlvmIrTranslator_impl::isReturnInstruction( - cs_insn& i) const -{ - return _returnInsnIds.count(i.id); -} - -template -bool Capstone2LlvmIrTranslator_impl::isBranchInstruction( - cs_insn& i) const -{ - return _branchInsnIds.count(i.id); -} - -template -bool Capstone2LlvmIrTranslator_impl::isCondBranchInstruction( - cs_insn& i) const -{ - return _condBranchInsnIds.count(i.id); -} - -// -//============================================================================== -// LLVM related getters and query methods. -//============================================================================== -// - -template -llvm::BranchInst* -Capstone2LlvmIrTranslator_impl::getCondBranchForInsnInIfThen( - llvm::Instruction* i) const -{ - // Asm to LLVM mapping instruction is not in BB where call is. - auto* prev = i->getPrevNode(); - while (prev) - { - if (isSpecialAsm2LlvmInstr(prev)) - { - return nullptr; - } - prev = prev->getPrevNode(); - } - - auto* prevBb = i->getParent()->getPrevNode(); - auto* term = prevBb ? prevBb->getTerminator() : nullptr; - auto* br = llvm::dyn_cast_or_null(term); - if (prevBb == nullptr - || br == nullptr - || !br->isConditional() - || br->getSuccessor(0) != i->getParent()) - { - return nullptr; - } - - return br; -} - -template -llvm::Module* Capstone2LlvmIrTranslator_impl::getModule() const -{ - return _module; -} - -template -bool Capstone2LlvmIrTranslator_impl::isSpecialAsm2LlvmMapGlobal( - llvm::Value* v) const -{ - return _asm2llvmGv == v; -} - -template -llvm::StoreInst* Capstone2LlvmIrTranslator_impl::isSpecialAsm2LlvmInstr( - llvm::Value* v) const -{ - if (auto* s = llvm::dyn_cast(v)) - { - if (isSpecialAsm2LlvmMapGlobal(s->getPointerOperand())) - { - return s; - } - } - return nullptr; -} - -template -llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::getAsm2LlvmMapGlobalVariable() const -{ - return _asm2llvmGv; -} - -template -bool Capstone2LlvmIrTranslator_impl::isCallFunction(llvm::Function* f) const -{ - return f == _callFunction; -} - -template -bool Capstone2LlvmIrTranslator_impl::isCallFunctionCall(llvm::CallInst* c) const -{ - return c ? isCallFunction(c->getCalledFunction()) : false; -} - -template -llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionCallFunctionCall(llvm::CallInst* c) const -{ - return isCallFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; -} - -template -llvm::Function* Capstone2LlvmIrTranslator_impl::getCallFunction() const -{ - return _callFunction; -} - -template -bool Capstone2LlvmIrTranslator_impl::isReturnFunction(llvm::Function* f) const -{ - return f == _returnFunction; -} - -template -bool Capstone2LlvmIrTranslator_impl::isReturnFunctionCall( - llvm::CallInst* c) const -{ - return c ? isReturnFunction(c->getCalledFunction()) : false; -} - -template -llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionReturnFunctionCall(llvm::CallInst* c) const -{ - return isReturnFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; -} - -template -llvm::Function* Capstone2LlvmIrTranslator_impl::getReturnFunction() const -{ - return _returnFunction; -} - -template -bool Capstone2LlvmIrTranslator_impl::isBranchFunction(llvm::Function* f) const -{ - return _branchFunction == f; -} - -template -bool Capstone2LlvmIrTranslator_impl::isBranchFunctionCall( - llvm::CallInst* c) const -{ - return c ? isBranchFunction(c->getCalledFunction()) : false; -} - -template -llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionBranchFunctionCall(llvm::CallInst* c) const -{ - return isBranchFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; -} - -template -llvm::Function* Capstone2LlvmIrTranslator_impl::getBranchFunction() const -{ - return _branchFunction; -} - -template -bool Capstone2LlvmIrTranslator_impl::isCondBranchFunction( - llvm::Function* f) const -{ - return _condBranchFunction == f; -} - -template -bool Capstone2LlvmIrTranslator_impl::isCondBranchFunctionCall( - llvm::CallInst* c) const -{ - return c ? isCondBranchFunction(c->getCalledFunction()) : false; -} - -template -llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionCondBranchFunctionCall( - llvm::CallInst* c) const -{ - return isCondBranchFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; -} - -template -llvm::Function* Capstone2LlvmIrTranslator_impl::getCondBranchFunction() const -{ - return _condBranchFunction; -} - -template -bool Capstone2LlvmIrTranslator_impl::isAnyPseudoFunction( - llvm::Function* f) const -{ - return isCallFunction(f) - || isReturnFunction(f) - || isBranchFunction(f) - || isCondBranchFunction(f); -} - -template -bool Capstone2LlvmIrTranslator_impl::isAnyPseudoFunctionCall( - llvm::CallInst* c) const -{ - return isCallFunctionCall(c) - || isReturnFunctionCall(c) - || isBranchFunctionCall(c) - || isCondBranchFunctionCall(c); -} - -template -llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::isRegister( - llvm::Value* v) const -{ - auto it = _llvm2CapstoneRegs.find(llvm::dyn_cast_or_null(v)); - return it != _llvm2CapstoneRegs.end() ? it->first : nullptr; -} - -template -uint32_t Capstone2LlvmIrTranslator_impl::getCapstoneRegister( - llvm::GlobalVariable* gv) const -{ - auto it = _llvm2CapstoneRegs.find(gv); - return it != _llvm2CapstoneRegs.end() ? it->second : 0; -} - -template -bool Capstone2LlvmIrTranslator_impl::isPseudoAsmFunction( - llvm::Function* f) const -{ - return _asmFunctions.count(f); -} - -template -bool Capstone2LlvmIrTranslator_impl::isPseudoAsmFunctionCall( - llvm::CallInst* c) const -{ - return c ? isPseudoAsmFunction(c->getCalledFunction()) : false; -} - -template -const std::set& Capstone2LlvmIrTranslator_impl::getPseudoAsmFunctions() const -{ - return _asmFunctions; -} - -// -//============================================================================== -// -//============================================================================== -// - -template -void Capstone2LlvmIrTranslator_impl::initialize() -{ - if (!isAllowedBasicMode(_basicMode)) - { - throw ModeSettingError( - _arch, - _basicMode, - ModeSettingError::eType::BASIC_MODE); - } - if (!isAllowedExtraMode(_extraMode)) - { - throw ModeSettingError( - _arch, - _extraMode, - ModeSettingError::eType::EXTRA_MODE); - } - - openHandle(); // Sets both _basicMode and _extraMode. - configureHandle(); - - initializeRegNameMap(); - initializeRegTypeMap(); - initializePseudoCallInstructionIDs(); - initializeArchSpecific(); - - generateEnvironment(); -} - -template -void Capstone2LlvmIrTranslator_impl::openHandle() -{ - cs_mode finalMode = static_cast(_basicMode + _extraMode); - if (cs_open(_arch, finalMode, &_handle) != CS_ERR_OK) - { - throw CapstoneError(cs_errno(_handle)); - } -} - -template -void Capstone2LlvmIrTranslator_impl::configureHandle() -{ - if (cs_option(_handle, CS_OPT_DETAIL, CS_OPT_ON) != CS_ERR_OK) - { - throw CapstoneError(cs_errno(_handle)); - } -} - -template -void Capstone2LlvmIrTranslator_impl::closeHandle() -{ - if (_handle != 0) - { - if (cs_close(&_handle) != CS_ERR_OK) - { - throw CapstoneError(cs_errno(_handle)); - } - } -} - -template -void Capstone2LlvmIrTranslator_impl::generateEnvironment() -{ - generateSpecialAsm2LlvmMapGlobal(); - generateCallFunction(); - generateReturnFunction(); - generateBranchFunction(); - generateCondBranchFunction(); - - generateEnvironmentArchSpecific(); - generateRegisters(); - generateDataLayout(); -} - -/** - * The generated global variable is unnamed. capstone2llvmir library does not - * allow to specify or set its name. Users can however get the variable with - * @c getAsm2LlvmMapGlobalVariable() and do whatever they want with it - * (e.g. rename). - */ -template -void Capstone2LlvmIrTranslator_impl::generateSpecialAsm2LlvmMapGlobal() -{ - llvm::GlobalValue::LinkageTypes lt = llvm::GlobalValue::InternalLinkage; - llvm::Constant* initializer = nullptr; - auto* t = llvm::IntegerType::getInt64Ty(_module->getContext()); - if (initializer == nullptr - && lt != llvm::GlobalValue::LinkageTypes::ExternalLinkage) - { - initializer = llvm::ConstantInt::get(t, 0); - } - - _asm2llvmGv = new llvm::GlobalVariable( - *_module, - t, - false, // isConstant - lt, - initializer); -} - -template -llvm::StoreInst* Capstone2LlvmIrTranslator_impl::generateSpecialAsm2LlvmInstr( - llvm::IRBuilder<>& irb, - cs_insn* i) -{ - retdec::common::Address a = i->address; - auto* gv = getAsm2LlvmMapGlobalVariable(); - auto* ci = llvm::ConstantInt::get(gv->getValueType(), a, false); - auto* s = irb.CreateStore(ci, gv, true); - return s; -} - -template -void Capstone2LlvmIrTranslator_impl::generateCallFunction() -{ - auto* ft = llvm::FunctionType::get( - llvm::Type::getVoidTy(_module->getContext()), - {llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}, - false); - _callFunction = llvm::Function::Create( - ft, - llvm::GlobalValue::LinkageTypes::ExternalLinkage, - "", - _module); -} - -template -llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCallFunctionCall( - llvm::IRBuilder<>& irb, - llvm::Value* t) -{ - auto* a1t = _callFunction->arg_begin()->getType(); - t = irb.CreateSExtOrTrunc(t, a1t); - _branchGenerated = irb.CreateCall(_callFunction, {t}); - return _branchGenerated; -} - -template -llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCondCallFunctionCall( - llvm::IRBuilder<>& irb, - llvm::Value* cond, - llvm::Value* t) -{ - auto bodyIrb = generateIfThen(cond, irb); - - auto* a1t = _callFunction->arg_begin()->getType(); - t = bodyIrb.CreateSExtOrTrunc(t, a1t); - _branchGenerated = bodyIrb.CreateCall(_callFunction, {t}); - _inCondition = true; - return _branchGenerated; -} - -template -void Capstone2LlvmIrTranslator_impl::generateReturnFunction() -{ - auto* ft = llvm::FunctionType::get( - llvm::Type::getVoidTy(_module->getContext()), - {llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}, - false); - _returnFunction = llvm::Function::Create( - ft, - llvm::GlobalValue::LinkageTypes::ExternalLinkage, - "", - _module); -} - -template -llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateReturnFunctionCall( - llvm::IRBuilder<>& irb, - llvm::Value* t) -{ - auto* a1t = _returnFunction->arg_begin()->getType(); - t = irb.CreateSExtOrTrunc(t, a1t); - _branchGenerated = irb.CreateCall(_returnFunction, {t}); - return _branchGenerated; -} - -template -llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCondReturnFunctionCall( - llvm::IRBuilder<>& irb, - llvm::Value* cond, - llvm::Value* t) -{ - auto bodyIrb = generateIfThen(cond, irb); - - auto* a1t = _returnFunction->arg_begin()->getType(); - t = bodyIrb.CreateSExtOrTrunc(t, a1t); - _branchGenerated = bodyIrb.CreateCall(_returnFunction, {t}); - _inCondition = true; - return _branchGenerated; -} - -template -void Capstone2LlvmIrTranslator_impl::generateBranchFunction() -{ - auto* ft = llvm::FunctionType::get( - llvm::Type::getVoidTy(_module->getContext()), - {llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}, - false); - _branchFunction = llvm::Function::Create( - ft, - llvm::GlobalValue::LinkageTypes::ExternalLinkage, - "", - _module); -} - -template -llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateBranchFunctionCall( - llvm::IRBuilder<>& irb, - llvm::Value* t) -{ - auto* a1t = _branchFunction->arg_begin()->getType(); - t = irb.CreateSExtOrTrunc(t, a1t); - _branchGenerated = irb.CreateCall(_branchFunction, {t}); - return _branchGenerated; -} - -template -void Capstone2LlvmIrTranslator_impl::generateCondBranchFunction() -{ - std::vector params = { - llvm::Type::getInt1Ty(_module->getContext()), - llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}; - auto* ft = llvm::FunctionType::get( - llvm::Type::getVoidTy(_module->getContext()), - params, - false); - _condBranchFunction = llvm::Function::Create( - ft, - llvm::GlobalValue::LinkageTypes::ExternalLinkage, - "", - _module); -} - -template -llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCondBranchFunctionCall( - llvm::IRBuilder<>& irb, - llvm::Value* cond, - llvm::Value* t) -{ - auto aIt = _condBranchFunction->arg_begin(); - ++aIt; - auto* a1t = aIt->getType(); - t = irb.CreateSExtOrTrunc(t, a1t); - _branchGenerated = irb.CreateCall(_condBranchFunction, {cond, t}); - return _branchGenerated; -} - -template -llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::createRegister( - uint32_t r, - llvm::GlobalValue::LinkageTypes lt, - llvm::Constant* initializer) -{ - auto* rt = getRegisterType(r); - if (initializer == nullptr - && lt != llvm::GlobalValue::LinkageTypes::ExternalLinkage) - { - if (auto* it = llvm::dyn_cast(rt)) - { - initializer = llvm::ConstantInt::get(it, 0); - } - else if (rt->isFloatingPointTy()) - { - initializer = llvm::ConstantFP::get(rt, 0); - } - else - { - throw GenericError("Unhandled register type."); - } - } - - auto* gv = new llvm::GlobalVariable( - *_module, - rt, - false, // isConstant - lt, - initializer, - getRegisterName(r)); - - if (gv == nullptr) - { - throw GenericError("Memory allocation error."); - } - - _llvm2CapstoneRegs[gv] = r; - _capstone2LlvmRegs[r] = gv; - - return gv; -} - -// -//============================================================================== -// Load/store methods. -//============================================================================== -// - -template -llvm::Value* Capstone2LlvmIrTranslator_impl::loadOp( - CInsn* ci, - llvm::IRBuilder<>& irb, - std::size_t idx, - llvm::Type* loadType, - llvm::Type* dstType, - eOpConv ct) -{ - if (ci->op_count <= idx) - { - throw GenericError( - "Idx out of bounds: "+std::to_string(idx) - +"/"+std::to_string(ci->op_count)); - } - - auto* op = loadOp(ci->operands[idx], irb, loadType); - if (op == nullptr) - { - throw GenericError("Operand loading failed."); - } - - if (dstType == nullptr) - { - return op; - } - - return generateTypeConversion(irb, op, dstType, ct); -} - -template -std::vector Capstone2LlvmIrTranslator_impl::_loadOps( - CInsn* ci, - llvm::IRBuilder<>& irb, - std::size_t opCnt, - bool strict, - llvm::Type* loadType, - llvm::Type* dstType, - eOpConv ct) -{ - if ((strict && (ci->op_count != opCnt)) || (ci->op_count < opCnt)) - { - throw GenericError( - "Trying to load " - +std::to_string(opCnt) - +" operands from instruction with" - +std::to_string(ci->op_count) - +" opernads."); - } - - std::size_t startOp = ci->op_count - opCnt; - - std::vector operands; - - // If no destination type specified, use type of first operand. - if (dstType == nullptr) - { - auto* op0 = loadOp(ci, irb, startOp, loadType, dstType, ct); - dstType = op0->getType(); - dstType = _checkTypeConversion(irb, dstType, ct); - op0 = generateTypeConversion(irb, op0, dstType, ct); - startOp++; - operands.push_back(op0); - } - else - { - auto* type = _checkTypeConversion(irb, dstType, ct); - if (type != dstType) - { - throw GenericError( - "Invalid combination of destination type and conversion type."); - } - } - - for (; startOp < ci->op_count; startOp++) { - auto* op = loadOp(ci, irb, startOp, loadType, dstType, ct); - operands.push_back(op); - } - - return operands; -} - -template -std::vector -Capstone2LlvmIrTranslator_impl::_loadOpsUniversal( - CInsn* ci, - llvm::IRBuilder<>& irb, - std::size_t opCnt, - bool strict, - eOpConv ict, - eOpConv fct) -{ - if ((strict && (ci->op_count != opCnt)) || (ci->op_count < opCnt)) - { - throw GenericError( - "Trying to load " - +std::to_string(opCnt) - +" operands from instruction with" - +std::to_string(ci->op_count) - +" opernads."); - } - - auto op0 = loadOp(ci, irb, ci->op_count - opCnt); - if (op0->getType()->isIntegerTy()) - { - auto operands = _loadOps(ci, irb, opCnt-1, false, nullptr, op0->getType(), ict); - operands.insert(operands.begin(), op0); - return operands; - } - - auto operands = _loadOps(ci, irb, opCnt-1, false, nullptr, op0->getType(), fct); - operands.insert(operands.begin(), op0); - return operands; -} - -/** - * Throws if op_count != 1. - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::loadOpUnary( - CInsn* ci, - llvm::IRBuilder<>& irb, - llvm::Type* loadType, - llvm::Type* dstType, - eOpConv ct) -{ - return _loadOps(ci, irb, 1, true, loadType, dstType, ct)[0]; -} - -/** - * Throws if op_count != 2. - */ -template -std::pair -Capstone2LlvmIrTranslator_impl::loadOpBinary( - CInsn* ci, - llvm::IRBuilder<>& irb, - eOpConv ct) -{ - auto operands = _loadOps(ci, irb, 2, true, nullptr, nullptr, ct); - return std::make_pair(operands[0], operands[1]); -} - -/** - * Throws if op_count != 2. - */ -template -std::pair -Capstone2LlvmIrTranslator_impl::loadOpBinary( - CInsn* ci, - llvm::IRBuilder<>& irb, - eOpConv ict, - eOpConv fct) -{ - auto operands = _loadOpsUniversal(ci, irb, 2, true, ict, fct); - return std::make_pair(operands[0], operands[1]); -} - -template -std::pair -Capstone2LlvmIrTranslator_impl::loadOpBinary( - CInsn* ci, - llvm::IRBuilder<>& irb, - llvm::Type* loadType, - llvm::Type* dstType, - eOpConv ct) -{ - auto operands = _loadOps(ci, irb, 2, true, loadType, dstType, ct); - return std::make_pair(operands[0], operands[1]); -} - -/** - * Throws if op_count != 2. - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::loadOpBinaryOp0( - CInsn* ci, - llvm::IRBuilder<>& irb, - llvm::Type* ty) -{ - auto operand = loadOp(ci, irb, 0, ty); - return operand; -} - -/** - * Throws if op_count != 2. - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::loadOpBinaryOp1( - CInsn* ci, - llvm::IRBuilder<>& irb, - llvm::Type* ty) -{ - auto operand = loadOp(ci, irb, 1, ty); - return operand; -} - -/** - * Throws if op_count != 3. - */ -template -std::tuple -Capstone2LlvmIrTranslator_impl::loadOpTernary( - CInsn* ci, - llvm::IRBuilder<>& irb, - eOpConv ct) -{ - auto operands = _loadOps(ci, irb, 3, true, nullptr, nullptr, ct); - return std::make_tuple(operands[0], operands[1], operands[2]); -} - -/** - * Throws if op_count != 3. - */ -template -std::tuple -Capstone2LlvmIrTranslator_impl::loadOpTernary( - CInsn* ci, - llvm::IRBuilder<>& irb, - eOpConv ict, - eOpConv fct) -{ - auto operands = _loadOpsUniversal(ci, irb, 3, true, ict, fct); - return std::make_tuple(operands[0], operands[1], operands[2]); -} - -/** - * Throws if op_count != 3. - */ -template -std::tuple -Capstone2LlvmIrTranslator_impl::loadOpTernary( - CInsn* ci, - llvm::IRBuilder<>& irb, - llvm::Type* loadType, - llvm::Type* dstType, - eOpConv ct) -{ - auto operands = _loadOps(ci, irb, 3, true, loadType, dstType, ct); - return std::make_tuple(operands[0], operands[1], operands[2]); -} - -/** - * Throws if op_count not in {2, 3}. - */ -template -std::pair -Capstone2LlvmIrTranslator_impl::loadOpBinaryOrTernaryOp1Op2( - CInsn* ci, - llvm::IRBuilder<>& irb, - eOpConv ct) -{ - auto operands = _loadOps(ci, irb, 2, false, nullptr, nullptr, ct); - return std::make_pair(operands[0], operands[1]); -} - -/** - * Throws if op_count not in {2, 3}. - */ -template -std::pair -Capstone2LlvmIrTranslator_impl::loadOpBinaryOrTernaryOp1Op2( - CInsn* ci, - llvm::IRBuilder<>& irb, - eOpConv ict, - eOpConv fct) -{ - auto operands = _loadOpsUniversal(ci, irb, 2, false, ict, fct); - return std::make_pair(operands[0], operands[1]); -} - -/** - * Throws if op_count != 4. - */ -template -std::tuple -Capstone2LlvmIrTranslator_impl::loadOpQuaternaryOp1Op2Op3( - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - auto operands = _loadOps(ci, irb, 3, false); - return std::make_tuple(operands[0], operands[1], operands[2]); -} - -// -//============================================================================== -// Carry/overflow/borrow add/sub generation routines. -//============================================================================== -// - -/** - * carry_add() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAdd( - llvm::Value* add, - llvm::Value* op0, - llvm::IRBuilder<>& irb) -{ - return irb.CreateICmpULT(add, op0); -} - -/** - * carry_add_c() - * - * If @p cf is not passed, default cf register is used. Why pass it? - * - Pass cf if you want to generate nicer code - prevent second cf load if - * it is already loaded by caller. This should however be taken care of by - * after generation optimizations. - * - Use a different value as cf. - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAddC( - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb, - llvm::Value* cf) -{ - auto* add1 = irb.CreateAdd(op0, op1); - if (cf == nullptr) - { - cf = loadRegister(getCarryRegister(), irb); - } - auto* cfc = irb.CreateZExtOrTrunc(cf, add1->getType()); - auto* add2 = irb.CreateAdd(add1, cfc); - auto* icmp1 = irb.CreateICmpULE(add2, op0); - auto* icmp2 = irb.CreateICmpULT(add1, op0); - auto* cff = irb.CreateZExtOrTrunc(cf, irb.getInt1Ty()); - return irb.CreateSelect(cff, icmp1, icmp2); -} - -/** - * carry_add_int4() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAddInt4( - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb) -{ - auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); - auto* and0 = irb.CreateAnd(op0, ci15); - auto* and1 = irb.CreateAnd(op1, ci15); - auto* add = irb.CreateAdd(and0, and1); - return irb.CreateICmpUGT(add, ci15); -} - -/** - * carry_add_c_int4() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAddCInt4( - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb, - llvm::Value* cf) -{ - auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); - auto* and0 = irb.CreateAnd(op0, ci15); - auto* and1 = irb.CreateAnd(op1, ci15); - auto* a = irb.CreateAdd(and0, and1); - if (cf == nullptr) - { - cf = loadRegister( - getCarryRegister(), - irb, - a->getType(), - eOpConv::ZEXT_TRUNC_OR_BITCAST); - } - auto* cfc = irb.CreateZExtOrTrunc(cf, a->getType()); - auto* add = irb.CreateAdd(a, cfc); - return irb.CreateICmpUGT(add, ci15); -} - -/** - * overflow_add() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowAdd( - llvm::Value* add, - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb) -{ - auto* xor0 = irb.CreateXor(op0, add); - auto* xor1 = irb.CreateXor(op1, add); - auto* ofAnd = irb.CreateAnd(xor0, xor1); - return irb.CreateICmpSLT( - ofAnd, - llvm::ConstantInt::get(ofAnd->getType(), 0)); -} - -/** - * overflow_add_c() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowAddC( - llvm::Value* add, - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb, - llvm::Value* cf) -{ - if (cf == nullptr) - { - cf = loadRegister(getCarryRegister(), irb); - } - auto* cfc = irb.CreateZExtOrTrunc(cf, add->getType()); - auto* ofAdd = irb.CreateAdd(add, cfc); - auto* xor0 = irb.CreateXor(op0, ofAdd); - auto* xor1 = irb.CreateXor(op1, ofAdd); - auto* ofAnd = irb.CreateAnd(xor0, xor1); - return irb.CreateICmpSLT(ofAnd, llvm::ConstantInt::get(ofAnd->getType(), 0)); -} - -/** - * overflow_sub() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowSub( - llvm::Value* sub, - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb) -{ - auto* xor0 = irb.CreateXor(op0, op1); - auto* xor1 = irb.CreateXor(op0, sub); - auto* ofAnd = irb.CreateAnd(xor0, xor1); - return irb.CreateICmpSLT( - ofAnd, - llvm::ConstantInt::get(ofAnd->getType(), 0)); -} - -/** - * overflow_sub_c() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowSubC( - llvm::Value* sub, - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb, - llvm::Value* cf) -{ - if (cf == nullptr) - { - cf = loadRegister(getCarryRegister(), irb); - } - auto* cfc = irb.CreateZExtOrTrunc(cf, sub->getType()); - auto* ofSub = irb.CreateSub(sub, cfc); - auto* xor0 = irb.CreateXor(op0, op1); - auto* xor1 = irb.CreateXor(op0, ofSub); - auto* ofAnd = irb.CreateAnd(xor0, xor1); - return irb.CreateICmpSLT( - ofAnd, - llvm::ConstantInt::get(ofAnd->getType(), 0)); -} - -/** - * borrow_sub() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSub( - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb) -{ - return irb.CreateICmpULT(op0, op1); -} - -/** - * borrow_sub_c() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSubC( - llvm::Value* sub, - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb, - llvm::Value* cf) -{ - if (cf == nullptr) - { - cf = loadRegister(getCarryRegister(), irb); - } - auto* cfc = irb.CreateZExtOrTrunc(cf, sub->getType()); - auto* cfSub = irb.CreateSub(sub, cfc); - auto* cfIcmp1 = irb.CreateICmpULT(op0, cfSub); - auto* negOne = llvm::ConstantInt::getSigned(op1->getType(), -1); - auto* cfIcmp2 = irb.CreateICmpULT(op1, negOne); - auto* cfOr = irb.CreateOr(cfIcmp1, cfIcmp2); - auto* cfIcmp3 = irb.CreateICmpULT(op0, op1); - auto* cff = irb.CreateZExtOrTrunc(cf, irb.getInt1Ty()); - return irb.CreateSelect(cff, cfOr, cfIcmp3); -} - -/** - * borrow_sub_int4() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSubInt4( - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb) -{ - auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); - auto* and0 = irb.CreateAnd(op0, ci15); - auto* and1 = irb.CreateAnd(op1, ci15); - auto* afSub = irb.CreateSub(and0, and1); - return irb.CreateICmpUGT(afSub, ci15); -} - -/** - * borrow_sub_c_int4() - */ -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSubCInt4( - llvm::Value* op0, - llvm::Value* op1, - llvm::IRBuilder<>& irb, - llvm::Value* cf) -{ - auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); - auto* and0 = irb.CreateAnd(op0, ci15); - auto* and1 = irb.CreateAnd(op1, ci15); - auto* sub = irb.CreateSub(and0, and1); - if (cf == nullptr) - { - cf = loadRegister(getCarryRegister(), irb); - } - auto* cfc = irb.CreateZExtOrTrunc(cf, sub->getType()); - auto* add = irb.CreateAdd(sub, cfc); - return irb.CreateICmpUGT(add, ci15); -} - -// -//============================================================================== -// Non-virtual helper methods. -//============================================================================== -// - -template -llvm::IntegerType* Capstone2LlvmIrTranslator_impl::getDefaultType() -{ - return getIntegerTypeFromByteSize(_module, getArchByteSize()); -} - -template -llvm::Value* Capstone2LlvmIrTranslator_impl::getThisInsnAddress( - cs_insn* i) -{ - return llvm::ConstantInt::get(getDefaultType(), i->address); -} - -template -llvm::Value* Capstone2LlvmIrTranslator_impl::getNextInsnAddress( - cs_insn* i) -{ - return llvm::ConstantInt::get(getDefaultType(), i->address + i->size); -} - -/** - * Generate pseudo assembly function name from the given instruction @a insn. - */ -template -std::string Capstone2LlvmIrTranslator_impl::getPseudoAsmFunctionName( - cs_insn* insn) -{ - return "__asm_" + std::string(insn->mnemonic); -} - -/** - * Get already existing asm functions associated with @p name, or if there - * is no such function, create it using @p name and @p type, add it to asm - * functions and return it. - * @return Functions associated with @p insnId. - */ -template -llvm::Function* Capstone2LlvmIrTranslator_impl::getPseudoAsmFunction( - cs_insn* insn, - llvm::FunctionType* type, - const std::string& name) -{ - auto n = name.empty() ? getPseudoAsmFunctionName(insn) : name; - auto p = std::make_pair(n, type); - auto fIt = _insn2asmFunctions.find(p); - if (fIt == _insn2asmFunctions.end()) - { - auto* fnc = llvm::Function::Create( - type, - llvm::GlobalValue::LinkageTypes::ExternalLinkage, - n, - _module); - _insn2asmFunctions[p] = fnc; - _asmFunctions.insert(fnc); - return fnc; - } - else - { - return fIt->second; - } -} - -/** - * The same as @c getPseudoAsmFunction(std::size_t,std::string&, llvm::FunctionType*), - * but function type is created by this variant. - */ -template -llvm::Function* Capstone2LlvmIrTranslator_impl::getPseudoAsmFunction( - cs_insn* insn, - llvm::Type* retType, - llvm::ArrayRef params, - const std::string& name) -{ - return getPseudoAsmFunction( - insn, - llvm::FunctionType::get(retType, params, false), - name); -} - -template -llvm::Value* Capstone2LlvmIrTranslator_impl::generateTypeConversion( - llvm::IRBuilder<>& irb, - llvm::Value* from, - llvm::Type* to, - eOpConv ct) -{ - if (to == nullptr || from->getType() == to) - { - return from; - } - - llvm::Value* ret = nullptr; - - switch (ct) - { - case eOpConv::SEXT_TRUNC_OR_BITCAST: - { - if (!to->isIntegerTy()) - { - throw GenericError("Invalid combination of conversion method and destination type"); - } - - if (from->getType()->isIntegerTy()) - { - ret = irb.CreateSExtOrTrunc(from, to); - } - else - { - auto size = _module->getDataLayout().getTypeStoreSizeInBits(from->getType()); - auto intTy = irb.getIntNTy(size); - ret = irb.CreateBitCast(from, intTy); - ret = irb.CreateZExtOrTrunc(ret, to); - } - break; - } - case eOpConv::ZEXT_TRUNC_OR_BITCAST: - { - if (!to->isIntegerTy()) - { - throw GenericError("Invalid combination of conversion method and destination type"); - } - - if (from->getType()->isIntegerTy()) - { - ret = irb.CreateZExtOrTrunc(from, to); - } - else - { - auto size = _module->getDataLayout().getTypeStoreSizeInBits(from->getType()); - auto intTy = irb.getIntNTy(size); - ret = irb.CreateBitCast(from, intTy); - ret = irb.CreateZExtOrTrunc(ret, to); - } - break; - } - case eOpConv::FPCAST_OR_BITCAST: - { - if (!to->isFloatingPointTy()) - { - throw GenericError("Invalid combination of conversion method and destination type"); - } - - if (from->getType()->isFloatingPointTy()) - { - ret = irb.CreateFPCast(from, to); - } - else - { - auto isize = _module->getDataLayout().getTypeStoreSizeInBits(from->getType()); - auto dsize = _module->getDataLayout().getTypeStoreSizeInBits(irb.getDoubleTy()); - auto fsize = _module->getDataLayout().getTypeStoreSizeInBits(irb.getFloatTy()); - auto lsize = _module->getDataLayout().getTypeStoreSizeInBits(llvm::Type::getFP128Ty(_module->getContext())); - - if (isize == fsize) - { - from = irb.CreateBitCast(from, irb.getFloatTy()); - } - else if (isize == dsize) - { - from = irb.CreateBitCast(from, irb.getDoubleTy()); - } - else if (isize == lsize) - { - from = irb.CreateBitCast(from, llvm::Type::getFP128Ty(_module->getContext())); - } - else - { - throw GenericError("Unable to create bitcast to floating point type."); - } - - ret = irb.CreateFPCast(from, to); - } - break; - } - case eOpConv::SITOFP_OR_FPCAST: - { - if (!to->isFloatingPointTy()) - { - throw GenericError("Invalid combination of conversion method and destination type"); - } - if (from->getType()->isFloatingPointTy()) - { - ret = irb.CreateFPCast(from, to); - } - else - { - ret = irb.CreateSIToFP(from, to); - } - break; - } - case eOpConv::UITOFP_OR_FPCAST: - { - if (!to->isFloatingPointTy()) - { - throw GenericError("Invalid combination of conversion method and destination type"); - } - if (from->getType()->isFloatingPointTy()) - { - ret = irb.CreateFPCast(from, to); - } - else - { - ret = irb.CreateUIToFP(from, to); - } - break; - } - case eOpConv::NOTHING: - { - ret = from; - break; - } - case eOpConv::THROW: - default: - { - throw GenericError("Unhandled eOpConv type."); - } - } - - return ret; -} - -template -llvm::Type* Capstone2LlvmIrTranslator_impl::_checkTypeConversion( - llvm::IRBuilder<>& irb, - llvm::Type* to, - eOpConv ct) -{ - switch (ct) - { - case eOpConv::ZEXT_TRUNC_OR_BITCAST: - case eOpConv::SEXT_TRUNC_OR_BITCAST: - { - if (!to->isIntegerTy()) - { - auto size = _module->getDataLayout().getTypeStoreSizeInBits(to); - return irb.getIntNTy(size); - } - break; - } - case eOpConv::FPCAST_OR_BITCAST: - case eOpConv::SITOFP_OR_FPCAST: - case eOpConv::UITOFP_OR_FPCAST: - { - if (!to->isFloatingPointTy()) - { - auto flSize = _module->getDataLayout().getTypeStoreSizeInBits( - irb.getFloatTy()); - auto size = _module->getDataLayout().getTypeStoreSizeInBits(to); - if (size <= flSize) - { - return irb.getFloatTy(); - } - - return irb.getDoubleTy(); - } - break; - } - default: - { - return to; - } - } - - return to; -} - -/** - * op0 = __asm_() - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0Fnc( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_UNARY(i, ci, irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - getDefaultType(), - llvm::ArrayRef{}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * __asm_(op0) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_UNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - irb.getVoidTy(), - llvm::ArrayRef{op0->getType()}); - - irb.CreateCall(fnc, llvm::ArrayRef{op0}); -} - -/** - * op0 = __asm_(op0) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_UNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - op0->getType(), - llvm::ArrayRef{op0->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * __asm_(op0, op1) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0Op1( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_BINARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - irb.getVoidTy(), - llvm::ArrayRef{op0->getType(), op1->getType()}); - - irb.CreateCall(fnc, llvm::ArrayRef{op0, op1}); -} - -/** - * op0 = __asm_(op1) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp1( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_BINARY(i, ci, irb); - - op1 = loadOp(ci->operands[1], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - op1->getType(), - llvm::ArrayRef{op1->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op1}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * op0 = __asm_(op0, op1) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0Op1( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_BINARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - op0->getType(), - llvm::ArrayRef{op0->getType(), op1->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * __asm_(op0, op1, op2) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0Op1Op2( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_TERNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - irb.getVoidTy(), - llvm::ArrayRef{ - op0->getType(), - op1->getType(), - op2->getType()}); - - irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2}); -} - -/** - * op0 = __asm_(op1, op2) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp1Op2( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_TERNARY(i, ci, irb); - - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - getDefaultType(), - llvm::ArrayRef{ - op1->getType(), - op2->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op1, op2}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * op0 = __asm_(op0, op1, op2) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0Op1Op2( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_TERNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - op0->getType(), - llvm::ArrayRef{ - op0->getType(), - op1->getType(), - op2->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * __asm_(op0, op1, op2, op3) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0Op1Op2Op3( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_QUATERNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - op3 = loadOp(ci->operands[3], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - irb.getVoidTy(), - llvm::ArrayRef{ - op0->getType(), - op1->getType(), - op2->getType(), - op3->getType()}); - - irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2, op3}); -} - -/** - * op0 = __asm_(op1, op2, op3) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp1Op2Op3( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_QUATERNARY(i, ci, irb); - - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - op3 = loadOp(ci->operands[3], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - getDefaultType(), - llvm::ArrayRef{ - op1->getType(), - op2->getType(), - op3->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op1, op2, op3}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * op0 = __asm_(op0, op1, op2, op3) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0Op1Op2Op3( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_QUATERNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - op3 = loadOp(ci->operands[3], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - op0->getType(), - llvm::ArrayRef{ - op0->getType(), - op1->getType(), - op2->getType(), - op3->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2, op3}); - - storeOp(ci->operands[0], c, irb); -} - -/** - * op0, op1 = __asm_(op0, op1, op2, op3) - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0Op1FncOp0Op1Op2Op3( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - EXPECT_IS_QUATERNARY(i, ci, irb); - - op0 = loadOp(ci->operands[0], irb); - op1 = loadOp(ci->operands[1], irb); - op2 = loadOp(ci->operands[2], irb); - op3 = loadOp(ci->operands[3], irb); - - llvm::Function* fnc = getPseudoAsmFunction( - i, - llvm::StructType::create(llvm::ArrayRef{ - op0->getType(), - op1->getType()}), - llvm::ArrayRef{ - op0->getType(), - op1->getType(), - op2->getType(), - op3->getType()}); - - auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2, op3}); - - storeOp(ci->operands[0], irb.CreateExtractValue(c, {0}), irb); - storeOp(ci->operands[1], irb.CreateExtractValue(c, {1}), irb); -} - -/** - * Some architectures do not have this info in operands. - * Return default value: CS_AC_INVALID. - */ -template -uint8_t Capstone2LlvmIrTranslator_impl::getOperandAccess(CInsnOp&) -{ - return CS_AC_INVALID; -} - -/** - * Generate pseudo asm call using information provided by Capstone. - */ -template -void Capstone2LlvmIrTranslator_impl::translatePseudoAsmGeneric( - cs_insn* i, - CInsn* ci, - llvm::IRBuilder<>& irb) -{ - std::vector vals; - std::vector types; - - unsigned writeCnt = 0; - llvm::Type* writeType = getDefaultType(); - bool writesOp = false; - for (std::size_t j = 0; j < ci->op_count; ++j) - { - auto& op = ci->operands[j]; - auto access = getOperandAccess(op); - if (access == CS_AC_INVALID || (access & CS_AC_READ)) - { - auto* o = loadOp(op, irb); - vals.push_back(o); - types.push_back(o->getType()); - } - - if (access & CS_AC_WRITE) - { - writesOp = true; - ++writeCnt; - - if (isOperandRegister(op)) - { - auto* t = getRegisterType(op.reg); - if (writeCnt == 1 || writeType == t) - { - writeType = t; - } - else - { - writeType = getDefaultType(); - } - } - else - { - writeType = getDefaultType(); - } - } - } - - if (vals.empty()) - { - // All registers must be ok, or don't use them at all. - std::vector readRegs; - readRegs.reserve(i->detail->regs_read_count); - for (std::size_t j = 0; j < i->detail->regs_read_count; ++j) - { - auto r = i->detail->regs_read[j]; - if (getRegister(r)) - { - readRegs.push_back(r); - } - else - { - readRegs.clear(); - break; - } - } - - for (auto r : readRegs) - { - auto* op = loadRegister(r, irb); - vals.push_back(op); - types.push_back(op->getType()); - } - } - - auto* retType = writesOp ? writeType : irb.getVoidTy(); - llvm::Function* fnc = getPseudoAsmFunction( - i, - retType, - types); - - auto* c = irb.CreateCall(fnc, vals); - - std::set writtenRegs; - if (retType) - { - for (std::size_t j = 0; j < ci->op_count; ++j) - { - auto& op = ci->operands[j]; - if (getOperandAccess(op) & CS_AC_WRITE) - { - storeOp(op, c, irb); - - if (isOperandRegister(op)) - { - writtenRegs.insert(op.reg); - } - } - } - } - - // All registers must be ok, or don't use them at all. - std::vector writeRegs; - writeRegs.reserve(i->detail->regs_write_count); - for (std::size_t j = 0; j < i->detail->regs_write_count; ++j) - { - auto r = i->detail->regs_write[j]; - if (writtenRegs.count(r)) - { - // silently ignore - } - else if (getRegister(r)) - { - writeRegs.push_back(r); - } - else - { - writeRegs.clear(); - break; - } - } - - for (auto r : writeRegs) - { - llvm::Value* val = retType->isVoidTy() - ? llvm::cast( - llvm::UndefValue::get(getRegisterType(r))) - : llvm::cast(c); - storeRegister(r, val, irb); - } -} - -template -void Capstone2LlvmIrTranslator_impl::throwUnexpectedOperands( - cs_insn* i, - const std::string comment) -{ - if (!isIgnoreUnexpectedOperands()) - { - throw UnexpectedOperandsError(i, comment); - } -} - -template -void Capstone2LlvmIrTranslator_impl::throwUnhandledInstructions( - cs_insn* i, - const std::string comment) -{ - if (!isIgnoreUnhandledInstructions()) - { - throw UnhandledInstructionError(i, comment); - } -} - -template class Capstone2LlvmIrTranslator_impl; -template class Capstone2LlvmIrTranslator_impl; -template class Capstone2LlvmIrTranslator_impl; -template class Capstone2LlvmIrTranslator_impl; -template class Capstone2LlvmIrTranslator_impl; - -} // namespace capstone2llvmir -} // namespace retdec +/** + * @file src/capstone2llvmir/capstone2llvmir.cpp + * @brief Converts bytes to Capstone representation, and Capstone representation + * to LLVM IR. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#include + +#include "capstone2llvmir/capstone2llvmir_impl.h" + +namespace retdec { +namespace capstone2llvmir { + +template +Capstone2LlvmIrTranslator_impl::Capstone2LlvmIrTranslator_impl( + cs_arch a, + cs_mode basic, + cs_mode extra, + llvm::Module* m) + : + _arch(a), + _basicMode(basic), + _extraMode(extra), + _origBasicMode(basic), + _module(m) +{ + // Do not call anything here, especially virtual methods. +} + +template +Capstone2LlvmIrTranslator_impl::~Capstone2LlvmIrTranslator_impl() +{ + closeHandle(); +} + +// +//============================================================================== +// Translator configuration methods. +//============================================================================== +// + +template +void Capstone2LlvmIrTranslator_impl::setIgnoreUnexpectedOperands(bool f) +{ + _ignoreUnexpectedOperands = f; +} + +template +void Capstone2LlvmIrTranslator_impl::setIgnoreUnhandledInstructions(bool f) +{ + _ignoreUnhandledInstructions = f; +} + +template +void Capstone2LlvmIrTranslator_impl::setGeneratePseudoAsmFunctions(bool f) +{ + _generatePseudoAsmFunctions = f; +} + +template +bool Capstone2LlvmIrTranslator_impl::isIgnoreUnexpectedOperands() const +{ + return _ignoreUnexpectedOperands; +} + +template +bool Capstone2LlvmIrTranslator_impl::isIgnoreUnhandledInstructions() const +{ + return _ignoreUnhandledInstructions; +} + +template +bool Capstone2LlvmIrTranslator_impl::isGeneratePseudoAsmFunctions() const +{ + return _generatePseudoAsmFunctions; +} + +// +//============================================================================== +// Mode query & modification methods - from Capstone2LlvmIrTranslator. +//============================================================================== +// + +template +void Capstone2LlvmIrTranslator_impl::modifyBasicMode(cs_mode m) +{ + if (!isAllowedBasicMode(m)) + { + throw ModeSettingError( + _arch, + m, + ModeSettingError::eType::BASIC_MODE); + } + + if (cs_option(_handle, CS_OPT_MODE, m + _extraMode) != CS_ERR_OK) + { + throw CapstoneError(cs_errno(_handle)); + } + + _basicMode = m; +} + +template +void Capstone2LlvmIrTranslator_impl::modifyExtraMode(cs_mode m) +{ + if (!isAllowedExtraMode(m)) + { + throw ModeSettingError( + _arch, + m, + ModeSettingError::eType::EXTRA_MODE); + } + + if (cs_option(_handle, CS_OPT_MODE, m + _basicMode) != CS_ERR_OK) + { + throw CapstoneError(cs_errno(_handle)); + } + + _extraMode = m; +} + +template +uint32_t Capstone2LlvmIrTranslator_impl::getArchBitSize() +{ + return getArchByteSize() * 8; +} + +// +//============================================================================== +// Translation methods - from Capstone2LlvmIrTranslator. +//============================================================================== +// + +// TODO: Optimize -- to make generation easier and nicer, some things +// can be generated suboptimally. We should inspect every generated +// ASM insruction and optimize some known patterns: +// +// 1. Load propagation: +// a = load r +// ... use a, not change r, no fnc call, etc. +// b = load r +// ... use b -> replace by a, remove b +// +// 2. Conversions: +// a = cast b +// ... use a +// c = cast b +// ... use c -> replace by a, remove c +// +// 3. Unused values (e.g. from loadOpBinary() where only one op used): +// a = load x +// ... a unused +// +// 4. Values used only for their type (e.g. op0 load in translateMov()): +// a = load x +// b = load y +// c = convert b to a.type +// store c x +// +// etc. + +template +typename Capstone2LlvmIrTranslator_impl::TranslationResult +Capstone2LlvmIrTranslator_impl::translate( + const uint8_t* bytes, + std::size_t size, + retdec::common::Address a, + llvm::IRBuilder<>& irb, + std::size_t count, + bool stopOnBranch) +{ + TranslationResult res; + + // We want to keep all Capstone instructions -> alloc a new one each time. + cs_insn* insn = cs_malloc(_handle); + + uint64_t address = a; + + _branchGenerated = nullptr; + _inCondition = false; + + // TODO: hack, solve better. + bool disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); + if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) + { + modifyBasicMode(CS_MODE_MIPS64); + disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); + modifyBasicMode(CS_MODE_MIPS32); + } + + while (disasmRes) + { + auto* a2l = generateSpecialAsm2LlvmInstr(irb, insn); + + res.insns.push_back(std::make_pair(a2l, insn)); + res.size = (insn->address + insn->size) - a; + + translateInstruction(insn, irb); + + ++res.count; + if (count && count == res.count) + { + return res; + } + + if (_branchGenerated && stopOnBranch) + { + res.branchCall = _branchGenerated; + res.inCondition = _inCondition; + return res; + } + + insn = cs_malloc(_handle); + + // TODO: hack, solve better. + disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); + if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) + { + modifyBasicMode(CS_MODE_MIPS64); + disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); + modifyBasicMode(CS_MODE_MIPS32); + } + } + + cs_free(insn, 1); + + return res; +} + +template +typename Capstone2LlvmIrTranslator_impl::TranslationResultOne +Capstone2LlvmIrTranslator_impl::translateOne( + const uint8_t*& bytes, + std::size_t& size, + retdec::common::Address& a, + llvm::IRBuilder<>& irb) +{ + TranslationResultOne res; + std::vector MPX_INSTRS{ + X86_INS_BNDMK, X86_INS_BNDCL, X86_INS_BNDCU, X86_INS_BNDMOV, X86_INS_BNDLDX, X86_INS_BNDSTX}; + bool MpxInstr = false; + + + // We want to keep all Capstone instructions -> alloc a new one each time. + cs_insn* insn = cs_malloc(_handle); + + uint64_t address = a; + _branchGenerated = nullptr; + _inCondition = false; + + // TODO: hack, solve better. + bool disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); + + for (auto& MpxIndexer : MPX_INSTRS) + { + if (insn[0].id == MpxIndexer) + MpxInstr = true; + } + + if (MpxInstr != true) + { + if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) + { + modifyBasicMode(CS_MODE_MIPS64); + disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); + modifyBasicMode(CS_MODE_MIPS32); + } + + if (disasmRes) + { + auto* a2l = generateSpecialAsm2LlvmInstr(irb, insn); + translateInstruction(insn, irb); + + res.llvmInsn = a2l; + res.capstoneInsn = insn; + res.size = insn->size; + res.branchCall = _branchGenerated; + res.inCondition = _inCondition; + + a = address; + } + else + { + cs_free(insn, 1); + } + } + else + { + auto* a2l = generateSpecialAsm2LlvmInstr(irb, insn); + + res.llvmInsn = a2l; + res.capstoneInsn = insn; + res.size = insn->size; + res.branchCall = _branchGenerated; + res.inCondition = _inCondition; + + a = address; + + return res; + } + return res; +} + +// +//============================================================================== +// Capstone related getters - from Capstone2LlvmIrTranslator. +//============================================================================== +// + +template +const csh& Capstone2LlvmIrTranslator_impl::getCapstoneEngine() const +{ + return _handle; +} + +template +cs_arch Capstone2LlvmIrTranslator_impl::getArchitecture() const +{ + return _arch; +} + +template +cs_mode Capstone2LlvmIrTranslator_impl::getBasicMode() const +{ + return _basicMode; +} + +template +cs_mode Capstone2LlvmIrTranslator_impl::getExtraMode() const +{ + return _extraMode; +} + +template +bool Capstone2LlvmIrTranslator_impl::hasDelaySlot(uint32_t id) const +{ + return false; +} + +template +bool Capstone2LlvmIrTranslator_impl::hasDelaySlotTypical(uint32_t id) const +{ + return false; +} + +template +bool Capstone2LlvmIrTranslator_impl::hasDelaySlotLikely(uint32_t id) const +{ + return false; +} + +template +std::size_t Capstone2LlvmIrTranslator_impl::getDelaySlot(uint32_t id) const +{ + return 0; +} + +template +llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::getRegister(uint32_t r) +{ + auto fIt = _capstone2LlvmRegs.find(r); + return fIt != _capstone2LlvmRegs.end() ? fIt->second : nullptr; +} + +template +std::string Capstone2LlvmIrTranslator_impl::getRegisterName(uint32_t r) const +{ + auto fIt = _reg2name.find(r); + if (fIt == _reg2name.end()) + { + if (auto* n = cs_reg_name(_handle, r)) + { + return n; + } + else + { + throw GenericError( + "Missing name for register number: " + std::to_string(r)); + } + } + else + { + return fIt->second; + } +} + +template +uint32_t Capstone2LlvmIrTranslator_impl::getRegisterBitSize(uint32_t r) const +{ + auto* rt = getRegisterType(r); + if (auto* it = llvm::dyn_cast(rt)) + { + return it->getBitWidth(); + } + else if (rt->isHalfTy()) + { + return 16; + } + else if (rt->isFloatTy()) + { + return 32; + } + else if (rt->isDoubleTy()) + { + return 64; + } + else if (rt->isX86_FP80Ty()) + { + return 80; + } + else if (rt->isFP128Ty()) + { + return 128; + } + else + { + throw GenericError( + "Unhandled type of register number: " + std::to_string(r)); + } +} + +template +uint32_t Capstone2LlvmIrTranslator_impl::getRegisterByteSize( + uint32_t r) const +{ + return getRegisterBitSize(r) / 8; +} + +template +llvm::Type* Capstone2LlvmIrTranslator_impl::getRegisterType( + uint32_t r) const +{ + auto fIt = _reg2type.find(r); + if (fIt == _reg2type.end()) + { + throw GenericError( + "Missing type for register number: " + std::to_string(r)); + } + return fIt->second; +} + +template +bool Capstone2LlvmIrTranslator_impl::isControlFlowInstruction( + cs_insn& i) const +{ + return _controlFlowInsnIds.count(i.id) + || isCallInstruction(i) + || isReturnInstruction(i) + || isBranchInstruction(i) + || isCondBranchInstruction(i); +} + +template +bool Capstone2LlvmIrTranslator_impl::isCallInstruction( + cs_insn& i) const +{ + return _callInsnIds.count(i.id); +} + +template +bool Capstone2LlvmIrTranslator_impl::isReturnInstruction( + cs_insn& i) const +{ + return _returnInsnIds.count(i.id); +} + +template +bool Capstone2LlvmIrTranslator_impl::isBranchInstruction( + cs_insn& i) const +{ + return _branchInsnIds.count(i.id); +} + +template +bool Capstone2LlvmIrTranslator_impl::isCondBranchInstruction( + cs_insn& i) const +{ + return _condBranchInsnIds.count(i.id); +} + +// +//============================================================================== +// LLVM related getters and query methods. +//============================================================================== +// + +template +llvm::BranchInst* +Capstone2LlvmIrTranslator_impl::getCondBranchForInsnInIfThen( + llvm::Instruction* i) const +{ + // Asm to LLVM mapping instruction is not in BB where call is. + auto* prev = i->getPrevNode(); + while (prev) + { + if (isSpecialAsm2LlvmInstr(prev)) + { + return nullptr; + } + prev = prev->getPrevNode(); + } + + auto* prevBb = i->getParent()->getPrevNode(); + auto* term = prevBb ? prevBb->getTerminator() : nullptr; + auto* br = llvm::dyn_cast_or_null(term); + if (prevBb == nullptr + || br == nullptr + || !br->isConditional() + || br->getSuccessor(0) != i->getParent()) + { + return nullptr; + } + + return br; +} + +template +llvm::Module* Capstone2LlvmIrTranslator_impl::getModule() const +{ + return _module; +} + +template +bool Capstone2LlvmIrTranslator_impl::isSpecialAsm2LlvmMapGlobal( + llvm::Value* v) const +{ + return _asm2llvmGv == v; +} + +template +llvm::StoreInst* Capstone2LlvmIrTranslator_impl::isSpecialAsm2LlvmInstr( + llvm::Value* v) const +{ + if (auto* s = llvm::dyn_cast(v)) + { + if (isSpecialAsm2LlvmMapGlobal(s->getPointerOperand())) + { + return s; + } + } + return nullptr; +} + +template +llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::getAsm2LlvmMapGlobalVariable() const +{ + return _asm2llvmGv; +} + +template +bool Capstone2LlvmIrTranslator_impl::isCallFunction(llvm::Function* f) const +{ + return f == _callFunction; +} + +template +bool Capstone2LlvmIrTranslator_impl::isCallFunctionCall(llvm::CallInst* c) const +{ + return c ? isCallFunction(c->getCalledFunction()) : false; +} + +template +llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionCallFunctionCall(llvm::CallInst* c) const +{ + return isCallFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; +} + +template +llvm::Function* Capstone2LlvmIrTranslator_impl::getCallFunction() const +{ + return _callFunction; +} + +template +bool Capstone2LlvmIrTranslator_impl::isReturnFunction(llvm::Function* f) const +{ + return f == _returnFunction; +} + +template +bool Capstone2LlvmIrTranslator_impl::isReturnFunctionCall( + llvm::CallInst* c) const +{ + return c ? isReturnFunction(c->getCalledFunction()) : false; +} + +template +llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionReturnFunctionCall(llvm::CallInst* c) const +{ + return isReturnFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; +} + +template +llvm::Function* Capstone2LlvmIrTranslator_impl::getReturnFunction() const +{ + return _returnFunction; +} + +template +bool Capstone2LlvmIrTranslator_impl::isBranchFunction(llvm::Function* f) const +{ + return _branchFunction == f; +} + +template +bool Capstone2LlvmIrTranslator_impl::isBranchFunctionCall( + llvm::CallInst* c) const +{ + return c ? isBranchFunction(c->getCalledFunction()) : false; +} + +template +llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionBranchFunctionCall(llvm::CallInst* c) const +{ + return isBranchFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; +} + +template +llvm::Function* Capstone2LlvmIrTranslator_impl::getBranchFunction() const +{ + return _branchFunction; +} + +template +bool Capstone2LlvmIrTranslator_impl::isCondBranchFunction( + llvm::Function* f) const +{ + return _condBranchFunction == f; +} + +template +bool Capstone2LlvmIrTranslator_impl::isCondBranchFunctionCall( + llvm::CallInst* c) const +{ + return c ? isCondBranchFunction(c->getCalledFunction()) : false; +} + +template +llvm::BranchInst* Capstone2LlvmIrTranslator_impl::isInConditionCondBranchFunctionCall( + llvm::CallInst* c) const +{ + return isCondBranchFunctionCall(c) ? getCondBranchForInsnInIfThen(c) : nullptr; +} + +template +llvm::Function* Capstone2LlvmIrTranslator_impl::getCondBranchFunction() const +{ + return _condBranchFunction; +} + +template +bool Capstone2LlvmIrTranslator_impl::isAnyPseudoFunction( + llvm::Function* f) const +{ + return isCallFunction(f) + || isReturnFunction(f) + || isBranchFunction(f) + || isCondBranchFunction(f); +} + +template +bool Capstone2LlvmIrTranslator_impl::isAnyPseudoFunctionCall( + llvm::CallInst* c) const +{ + return isCallFunctionCall(c) + || isReturnFunctionCall(c) + || isBranchFunctionCall(c) + || isCondBranchFunctionCall(c); +} + +template +llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::isRegister( + llvm::Value* v) const +{ + auto it = _llvm2CapstoneRegs.find(llvm::dyn_cast_or_null(v)); + return it != _llvm2CapstoneRegs.end() ? it->first : nullptr; +} + +template +uint32_t Capstone2LlvmIrTranslator_impl::getCapstoneRegister( + llvm::GlobalVariable* gv) const +{ + auto it = _llvm2CapstoneRegs.find(gv); + return it != _llvm2CapstoneRegs.end() ? it->second : 0; +} + +template +bool Capstone2LlvmIrTranslator_impl::isPseudoAsmFunction( + llvm::Function* f) const +{ + return _asmFunctions.count(f); +} + +template +bool Capstone2LlvmIrTranslator_impl::isPseudoAsmFunctionCall( + llvm::CallInst* c) const +{ + return c ? isPseudoAsmFunction(c->getCalledFunction()) : false; +} + +template +const std::set& Capstone2LlvmIrTranslator_impl::getPseudoAsmFunctions() const +{ + return _asmFunctions; +} + +// +//============================================================================== +// +//============================================================================== +// + +template +void Capstone2LlvmIrTranslator_impl::initialize() +{ + if (!isAllowedBasicMode(_basicMode)) + { + throw ModeSettingError( + _arch, + _basicMode, + ModeSettingError::eType::BASIC_MODE); + } + if (!isAllowedExtraMode(_extraMode)) + { + throw ModeSettingError( + _arch, + _extraMode, + ModeSettingError::eType::EXTRA_MODE); + } + + openHandle(); // Sets both _basicMode and _extraMode. + configureHandle(); + + initializeRegNameMap(); + initializeRegTypeMap(); + initializePseudoCallInstructionIDs(); + initializeArchSpecific(); + + generateEnvironment(); +} + +template +void Capstone2LlvmIrTranslator_impl::openHandle() +{ + cs_mode finalMode = static_cast(_basicMode + _extraMode); + if (cs_open(_arch, finalMode, &_handle) != CS_ERR_OK) + { + throw CapstoneError(cs_errno(_handle)); + } +} + +template +void Capstone2LlvmIrTranslator_impl::configureHandle() +{ + if (cs_option(_handle, CS_OPT_DETAIL, CS_OPT_ON) != CS_ERR_OK) + { + throw CapstoneError(cs_errno(_handle)); + } +} + +template +void Capstone2LlvmIrTranslator_impl::closeHandle() +{ + if (_handle != 0) + { + if (cs_close(&_handle) != CS_ERR_OK) + { + throw CapstoneError(cs_errno(_handle)); + } + } +} + +template +void Capstone2LlvmIrTranslator_impl::generateEnvironment() +{ + generateSpecialAsm2LlvmMapGlobal(); + generateCallFunction(); + generateReturnFunction(); + generateBranchFunction(); + generateCondBranchFunction(); + + generateEnvironmentArchSpecific(); + generateRegisters(); + generateDataLayout(); +} + +/** + * The generated global variable is unnamed. capstone2llvmir library does not + * allow to specify or set its name. Users can however get the variable with + * @c getAsm2LlvmMapGlobalVariable() and do whatever they want with it + * (e.g. rename). + */ +template +void Capstone2LlvmIrTranslator_impl::generateSpecialAsm2LlvmMapGlobal() +{ + llvm::GlobalValue::LinkageTypes lt = llvm::GlobalValue::InternalLinkage; + llvm::Constant* initializer = nullptr; + auto* t = llvm::IntegerType::getInt64Ty(_module->getContext()); + if (initializer == nullptr + && lt != llvm::GlobalValue::LinkageTypes::ExternalLinkage) + { + initializer = llvm::ConstantInt::get(t, 0); + } + + _asm2llvmGv = new llvm::GlobalVariable( + *_module, + t, + false, // isConstant + lt, + initializer); +} + +template +llvm::StoreInst* Capstone2LlvmIrTranslator_impl::generateSpecialAsm2LlvmInstr( + llvm::IRBuilder<>& irb, + cs_insn* i) +{ + retdec::common::Address a = i->address; + auto* gv = getAsm2LlvmMapGlobalVariable(); + auto* ci = llvm::ConstantInt::get(gv->getValueType(), a, false); + auto* s = irb.CreateStore(ci, gv, true); + return s; +} + +template +void Capstone2LlvmIrTranslator_impl::generateCallFunction() +{ + auto* ft = llvm::FunctionType::get( + llvm::Type::getVoidTy(_module->getContext()), + {llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}, + false); + _callFunction = llvm::Function::Create( + ft, + llvm::GlobalValue::LinkageTypes::ExternalLinkage, + "", + _module); +} + +template +llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCallFunctionCall( + llvm::IRBuilder<>& irb, + llvm::Value* t) +{ + auto* a1t = _callFunction->arg_begin()->getType(); + t = irb.CreateSExtOrTrunc(t, a1t); + _branchGenerated = irb.CreateCall(_callFunction, {t}); + return _branchGenerated; +} + +template +llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCondCallFunctionCall( + llvm::IRBuilder<>& irb, + llvm::Value* cond, + llvm::Value* t) +{ + auto bodyIrb = generateIfThen(cond, irb); + + auto* a1t = _callFunction->arg_begin()->getType(); + t = bodyIrb.CreateSExtOrTrunc(t, a1t); + _branchGenerated = bodyIrb.CreateCall(_callFunction, {t}); + _inCondition = true; + return _branchGenerated; +} + +template +void Capstone2LlvmIrTranslator_impl::generateReturnFunction() +{ + auto* ft = llvm::FunctionType::get( + llvm::Type::getVoidTy(_module->getContext()), + {llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}, + false); + _returnFunction = llvm::Function::Create( + ft, + llvm::GlobalValue::LinkageTypes::ExternalLinkage, + "", + _module); +} + +template +llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateReturnFunctionCall( + llvm::IRBuilder<>& irb, + llvm::Value* t) +{ + auto* a1t = _returnFunction->arg_begin()->getType(); + t = irb.CreateSExtOrTrunc(t, a1t); + _branchGenerated = irb.CreateCall(_returnFunction, {t}); + return _branchGenerated; +} + +template +llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCondReturnFunctionCall( + llvm::IRBuilder<>& irb, + llvm::Value* cond, + llvm::Value* t) +{ + auto bodyIrb = generateIfThen(cond, irb); + + auto* a1t = _returnFunction->arg_begin()->getType(); + t = bodyIrb.CreateSExtOrTrunc(t, a1t); + _branchGenerated = bodyIrb.CreateCall(_returnFunction, {t}); + _inCondition = true; + return _branchGenerated; +} + +template +void Capstone2LlvmIrTranslator_impl::generateBranchFunction() +{ + auto* ft = llvm::FunctionType::get( + llvm::Type::getVoidTy(_module->getContext()), + {llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}, + false); + _branchFunction = llvm::Function::Create( + ft, + llvm::GlobalValue::LinkageTypes::ExternalLinkage, + "", + _module); +} + +template +llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateBranchFunctionCall( + llvm::IRBuilder<>& irb, + llvm::Value* t) +{ + auto* a1t = _branchFunction->arg_begin()->getType(); + t = irb.CreateSExtOrTrunc(t, a1t); + _branchGenerated = irb.CreateCall(_branchFunction, {t}); + return _branchGenerated; +} + +template +void Capstone2LlvmIrTranslator_impl::generateCondBranchFunction() +{ + std::vector params = { + llvm::Type::getInt1Ty(_module->getContext()), + llvm::Type::getIntNTy(_module->getContext(), getArchBitSize())}; + auto* ft = llvm::FunctionType::get( + llvm::Type::getVoidTy(_module->getContext()), + params, + false); + _condBranchFunction = llvm::Function::Create( + ft, + llvm::GlobalValue::LinkageTypes::ExternalLinkage, + "", + _module); +} + +template +llvm::CallInst* Capstone2LlvmIrTranslator_impl::generateCondBranchFunctionCall( + llvm::IRBuilder<>& irb, + llvm::Value* cond, + llvm::Value* t) +{ + auto aIt = _condBranchFunction->arg_begin(); + ++aIt; + auto* a1t = aIt->getType(); + t = irb.CreateSExtOrTrunc(t, a1t); + _branchGenerated = irb.CreateCall(_condBranchFunction, {cond, t}); + return _branchGenerated; +} + +template +llvm::GlobalVariable* Capstone2LlvmIrTranslator_impl::createRegister( + uint32_t r, + llvm::GlobalValue::LinkageTypes lt, + llvm::Constant* initializer) +{ + auto* rt = getRegisterType(r); + if (initializer == nullptr + && lt != llvm::GlobalValue::LinkageTypes::ExternalLinkage) + { + if (auto* it = llvm::dyn_cast(rt)) + { + initializer = llvm::ConstantInt::get(it, 0); + } + else if (rt->isFloatingPointTy()) + { + initializer = llvm::ConstantFP::get(rt, 0); + } + else + { + throw GenericError("Unhandled register type."); + } + } + + auto* gv = new llvm::GlobalVariable( + *_module, + rt, + false, // isConstant + lt, + initializer, + getRegisterName(r)); + + if (gv == nullptr) + { + throw GenericError("Memory allocation error."); + } + + _llvm2CapstoneRegs[gv] = r; + _capstone2LlvmRegs[r] = gv; + + return gv; +} + +// +//============================================================================== +// Load/store methods. +//============================================================================== +// + +template +llvm::Value* Capstone2LlvmIrTranslator_impl::loadOp( + CInsn* ci, + llvm::IRBuilder<>& irb, + std::size_t idx, + llvm::Type* loadType, + llvm::Type* dstType, + eOpConv ct) +{ + if (ci->op_count <= idx) + { + throw GenericError( + "Idx out of bounds: "+std::to_string(idx) + +"/"+std::to_string(ci->op_count)); + } + + auto* op = loadOp(ci->operands[idx], irb, loadType); + if (op == nullptr) + { + throw GenericError("Operand loading failed."); + } + + if (dstType == nullptr) + { + return op; + } + + return generateTypeConversion(irb, op, dstType, ct); +} + +template +std::vector Capstone2LlvmIrTranslator_impl::_loadOps( + CInsn* ci, + llvm::IRBuilder<>& irb, + std::size_t opCnt, + bool strict, + llvm::Type* loadType, + llvm::Type* dstType, + eOpConv ct) +{ + if ((strict && (ci->op_count != opCnt)) || (ci->op_count < opCnt)) + { + throw GenericError( + "Trying to load " + +std::to_string(opCnt) + +" operands from instruction with" + +std::to_string(ci->op_count) + +" opernads."); + } + + std::size_t startOp = ci->op_count - opCnt; + + std::vector operands; + + // If no destination type specified, use type of first operand. + if (dstType == nullptr) + { + auto* op0 = loadOp(ci, irb, startOp, loadType, dstType, ct); + dstType = op0->getType(); + dstType = _checkTypeConversion(irb, dstType, ct); + op0 = generateTypeConversion(irb, op0, dstType, ct); + startOp++; + operands.push_back(op0); + } + else + { + auto* type = _checkTypeConversion(irb, dstType, ct); + if (type != dstType) + { + throw GenericError( + "Invalid combination of destination type and conversion type."); + } + } + + for (; startOp < ci->op_count; startOp++) { + auto* op = loadOp(ci, irb, startOp, loadType, dstType, ct); + operands.push_back(op); + } + + return operands; +} + +template +std::vector +Capstone2LlvmIrTranslator_impl::_loadOpsUniversal( + CInsn* ci, + llvm::IRBuilder<>& irb, + std::size_t opCnt, + bool strict, + eOpConv ict, + eOpConv fct) +{ + if ((strict && (ci->op_count != opCnt)) || (ci->op_count < opCnt)) + { + throw GenericError( + "Trying to load " + +std::to_string(opCnt) + +" operands from instruction with" + +std::to_string(ci->op_count) + +" opernads."); + } + + auto op0 = loadOp(ci, irb, ci->op_count - opCnt); + if (op0->getType()->isIntegerTy()) + { + auto operands = _loadOps(ci, irb, opCnt-1, false, nullptr, op0->getType(), ict); + operands.insert(operands.begin(), op0); + return operands; + } + + auto operands = _loadOps(ci, irb, opCnt-1, false, nullptr, op0->getType(), fct); + operands.insert(operands.begin(), op0); + return operands; +} + +/** + * Throws if op_count != 1. + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::loadOpUnary( + CInsn* ci, + llvm::IRBuilder<>& irb, + llvm::Type* loadType, + llvm::Type* dstType, + eOpConv ct) +{ + return _loadOps(ci, irb, 1, true, loadType, dstType, ct)[0]; +} + +/** + * Throws if op_count != 2. + */ +template +std::pair +Capstone2LlvmIrTranslator_impl::loadOpBinary( + CInsn* ci, + llvm::IRBuilder<>& irb, + eOpConv ct) +{ + auto operands = _loadOps(ci, irb, 2, true, nullptr, nullptr, ct); + return std::make_pair(operands[0], operands[1]); +} + +/** + * Throws if op_count != 2. + */ +template +std::pair +Capstone2LlvmIrTranslator_impl::loadOpBinary( + CInsn* ci, + llvm::IRBuilder<>& irb, + eOpConv ict, + eOpConv fct) +{ + auto operands = _loadOpsUniversal(ci, irb, 2, true, ict, fct); + return std::make_pair(operands[0], operands[1]); +} + +template +std::pair +Capstone2LlvmIrTranslator_impl::loadOpBinary( + CInsn* ci, + llvm::IRBuilder<>& irb, + llvm::Type* loadType, + llvm::Type* dstType, + eOpConv ct) +{ + auto operands = _loadOps(ci, irb, 2, true, loadType, dstType, ct); + return std::make_pair(operands[0], operands[1]); +} + +/** + * Throws if op_count != 2. + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::loadOpBinaryOp0( + CInsn* ci, + llvm::IRBuilder<>& irb, + llvm::Type* ty) +{ + auto operand = loadOp(ci, irb, 0, ty); + return operand; +} + +/** + * Throws if op_count != 2. + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::loadOpBinaryOp1( + CInsn* ci, + llvm::IRBuilder<>& irb, + llvm::Type* ty) +{ + auto operand = loadOp(ci, irb, 1, ty); + return operand; +} + +/** + * Throws if op_count != 3. + */ +template +std::tuple +Capstone2LlvmIrTranslator_impl::loadOpTernary( + CInsn* ci, + llvm::IRBuilder<>& irb, + eOpConv ct) +{ + auto operands = _loadOps(ci, irb, 3, true, nullptr, nullptr, ct); + return std::make_tuple(operands[0], operands[1], operands[2]); +} + +/** + * Throws if op_count != 3. + */ +template +std::tuple +Capstone2LlvmIrTranslator_impl::loadOpTernary( + CInsn* ci, + llvm::IRBuilder<>& irb, + eOpConv ict, + eOpConv fct) +{ + auto operands = _loadOpsUniversal(ci, irb, 3, true, ict, fct); + return std::make_tuple(operands[0], operands[1], operands[2]); +} + +/** + * Throws if op_count != 3. + */ +template +std::tuple +Capstone2LlvmIrTranslator_impl::loadOpTernary( + CInsn* ci, + llvm::IRBuilder<>& irb, + llvm::Type* loadType, + llvm::Type* dstType, + eOpConv ct) +{ + auto operands = _loadOps(ci, irb, 3, true, loadType, dstType, ct); + return std::make_tuple(operands[0], operands[1], operands[2]); +} + +/** + * Throws if op_count not in {2, 3}. + */ +template +std::pair +Capstone2LlvmIrTranslator_impl::loadOpBinaryOrTernaryOp1Op2( + CInsn* ci, + llvm::IRBuilder<>& irb, + eOpConv ct) +{ + auto operands = _loadOps(ci, irb, 2, false, nullptr, nullptr, ct); + return std::make_pair(operands[0], operands[1]); +} + +/** + * Throws if op_count not in {2, 3}. + */ +template +std::pair +Capstone2LlvmIrTranslator_impl::loadOpBinaryOrTernaryOp1Op2( + CInsn* ci, + llvm::IRBuilder<>& irb, + eOpConv ict, + eOpConv fct) +{ + auto operands = _loadOpsUniversal(ci, irb, 2, false, ict, fct); + return std::make_pair(operands[0], operands[1]); +} + +/** + * Throws if op_count != 4. + */ +template +std::tuple +Capstone2LlvmIrTranslator_impl::loadOpQuaternaryOp1Op2Op3( + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + auto operands = _loadOps(ci, irb, 3, false); + return std::make_tuple(operands[0], operands[1], operands[2]); +} + +// +//============================================================================== +// Carry/overflow/borrow add/sub generation routines. +//============================================================================== +// + +/** + * carry_add() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAdd( + llvm::Value* add, + llvm::Value* op0, + llvm::IRBuilder<>& irb) +{ + return irb.CreateICmpULT(add, op0); +} + +/** + * carry_add_c() + * + * If @p cf is not passed, default cf register is used. Why pass it? + * - Pass cf if you want to generate nicer code - prevent second cf load if + * it is already loaded by caller. This should however be taken care of by + * after generation optimizations. + * - Use a different value as cf. + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAddC( + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb, + llvm::Value* cf) +{ + auto* add1 = irb.CreateAdd(op0, op1); + if (cf == nullptr) + { + cf = loadRegister(getCarryRegister(), irb); + } + auto* cfc = irb.CreateZExtOrTrunc(cf, add1->getType()); + auto* add2 = irb.CreateAdd(add1, cfc); + auto* icmp1 = irb.CreateICmpULE(add2, op0); + auto* icmp2 = irb.CreateICmpULT(add1, op0); + auto* cff = irb.CreateZExtOrTrunc(cf, irb.getInt1Ty()); + return irb.CreateSelect(cff, icmp1, icmp2); +} + +/** + * carry_add_int4() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAddInt4( + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb) +{ + auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); + auto* and0 = irb.CreateAnd(op0, ci15); + auto* and1 = irb.CreateAnd(op1, ci15); + auto* add = irb.CreateAdd(and0, and1); + return irb.CreateICmpUGT(add, ci15); +} + +/** + * carry_add_c_int4() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateCarryAddCInt4( + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb, + llvm::Value* cf) +{ + auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); + auto* and0 = irb.CreateAnd(op0, ci15); + auto* and1 = irb.CreateAnd(op1, ci15); + auto* a = irb.CreateAdd(and0, and1); + if (cf == nullptr) + { + cf = loadRegister( + getCarryRegister(), + irb, + a->getType(), + eOpConv::ZEXT_TRUNC_OR_BITCAST); + } + auto* cfc = irb.CreateZExtOrTrunc(cf, a->getType()); + auto* add = irb.CreateAdd(a, cfc); + return irb.CreateICmpUGT(add, ci15); +} + +/** + * overflow_add() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowAdd( + llvm::Value* add, + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb) +{ + auto* xor0 = irb.CreateXor(op0, add); + auto* xor1 = irb.CreateXor(op1, add); + auto* ofAnd = irb.CreateAnd(xor0, xor1); + return irb.CreateICmpSLT( + ofAnd, + llvm::ConstantInt::get(ofAnd->getType(), 0)); +} + +/** + * overflow_add_c() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowAddC( + llvm::Value* add, + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb, + llvm::Value* cf) +{ + if (cf == nullptr) + { + cf = loadRegister(getCarryRegister(), irb); + } + auto* cfc = irb.CreateZExtOrTrunc(cf, add->getType()); + auto* ofAdd = irb.CreateAdd(add, cfc); + auto* xor0 = irb.CreateXor(op0, ofAdd); + auto* xor1 = irb.CreateXor(op1, ofAdd); + auto* ofAnd = irb.CreateAnd(xor0, xor1); + return irb.CreateICmpSLT(ofAnd, llvm::ConstantInt::get(ofAnd->getType(), 0)); +} + +/** + * overflow_sub() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowSub( + llvm::Value* sub, + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb) +{ + auto* xor0 = irb.CreateXor(op0, op1); + auto* xor1 = irb.CreateXor(op0, sub); + auto* ofAnd = irb.CreateAnd(xor0, xor1); + return irb.CreateICmpSLT( + ofAnd, + llvm::ConstantInt::get(ofAnd->getType(), 0)); +} + +/** + * overflow_sub_c() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateOverflowSubC( + llvm::Value* sub, + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb, + llvm::Value* cf) +{ + if (cf == nullptr) + { + cf = loadRegister(getCarryRegister(), irb); + } + auto* cfc = irb.CreateZExtOrTrunc(cf, sub->getType()); + auto* ofSub = irb.CreateSub(sub, cfc); + auto* xor0 = irb.CreateXor(op0, op1); + auto* xor1 = irb.CreateXor(op0, ofSub); + auto* ofAnd = irb.CreateAnd(xor0, xor1); + return irb.CreateICmpSLT( + ofAnd, + llvm::ConstantInt::get(ofAnd->getType(), 0)); +} + +/** + * borrow_sub() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSub( + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb) +{ + return irb.CreateICmpULT(op0, op1); +} + +/** + * borrow_sub_c() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSubC( + llvm::Value* sub, + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb, + llvm::Value* cf) +{ + if (cf == nullptr) + { + cf = loadRegister(getCarryRegister(), irb); + } + auto* cfc = irb.CreateZExtOrTrunc(cf, sub->getType()); + auto* cfSub = irb.CreateSub(sub, cfc); + auto* cfIcmp1 = irb.CreateICmpULT(op0, cfSub); + auto* negOne = llvm::ConstantInt::getSigned(op1->getType(), -1); + auto* cfIcmp2 = irb.CreateICmpULT(op1, negOne); + auto* cfOr = irb.CreateOr(cfIcmp1, cfIcmp2); + auto* cfIcmp3 = irb.CreateICmpULT(op0, op1); + auto* cff = irb.CreateZExtOrTrunc(cf, irb.getInt1Ty()); + return irb.CreateSelect(cff, cfOr, cfIcmp3); +} + +/** + * borrow_sub_int4() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSubInt4( + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb) +{ + auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); + auto* and0 = irb.CreateAnd(op0, ci15); + auto* and1 = irb.CreateAnd(op1, ci15); + auto* afSub = irb.CreateSub(and0, and1); + return irb.CreateICmpUGT(afSub, ci15); +} + +/** + * borrow_sub_c_int4() + */ +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateBorrowSubCInt4( + llvm::Value* op0, + llvm::Value* op1, + llvm::IRBuilder<>& irb, + llvm::Value* cf) +{ + auto* ci15 = llvm::ConstantInt::get(op0->getType(), 15); + auto* and0 = irb.CreateAnd(op0, ci15); + auto* and1 = irb.CreateAnd(op1, ci15); + auto* sub = irb.CreateSub(and0, and1); + if (cf == nullptr) + { + cf = loadRegister(getCarryRegister(), irb); + } + auto* cfc = irb.CreateZExtOrTrunc(cf, sub->getType()); + auto* add = irb.CreateAdd(sub, cfc); + return irb.CreateICmpUGT(add, ci15); +} + +// +//============================================================================== +// Non-virtual helper methods. +//============================================================================== +// + +template +llvm::IntegerType* Capstone2LlvmIrTranslator_impl::getDefaultType() +{ + return getIntegerTypeFromByteSize(_module, getArchByteSize()); +} + +template +llvm::Value* Capstone2LlvmIrTranslator_impl::getThisInsnAddress( + cs_insn* i) +{ + return llvm::ConstantInt::get(getDefaultType(), i->address); +} + +template +llvm::Value* Capstone2LlvmIrTranslator_impl::getNextInsnAddress( + cs_insn* i) +{ + return llvm::ConstantInt::get(getDefaultType(), i->address + i->size); +} + +/** + * Generate pseudo assembly function name from the given instruction @a insn. + */ +template +std::string Capstone2LlvmIrTranslator_impl::getPseudoAsmFunctionName( + cs_insn* insn) +{ + return "__asm_" + std::string(insn->mnemonic); +} + +/** + * Get already existing asm functions associated with @p name, or if there + * is no such function, create it using @p name and @p type, add it to asm + * functions and return it. + * @return Functions associated with @p insnId. + */ +template +llvm::Function* Capstone2LlvmIrTranslator_impl::getPseudoAsmFunction( + cs_insn* insn, + llvm::FunctionType* type, + const std::string& name) +{ + auto n = name.empty() ? getPseudoAsmFunctionName(insn) : name; + auto p = std::make_pair(n, type); + auto fIt = _insn2asmFunctions.find(p); + if (fIt == _insn2asmFunctions.end()) + { + auto* fnc = llvm::Function::Create( + type, + llvm::GlobalValue::LinkageTypes::ExternalLinkage, + n, + _module); + _insn2asmFunctions[p] = fnc; + _asmFunctions.insert(fnc); + return fnc; + } + else + { + return fIt->second; + } +} + +/** + * The same as @c getPseudoAsmFunction(std::size_t,std::string&, llvm::FunctionType*), + * but function type is created by this variant. + */ +template +llvm::Function* Capstone2LlvmIrTranslator_impl::getPseudoAsmFunction( + cs_insn* insn, + llvm::Type* retType, + llvm::ArrayRef params, + const std::string& name) +{ + return getPseudoAsmFunction( + insn, + llvm::FunctionType::get(retType, params, false), + name); +} + +template +llvm::Value* Capstone2LlvmIrTranslator_impl::generateTypeConversion( + llvm::IRBuilder<>& irb, + llvm::Value* from, + llvm::Type* to, + eOpConv ct) +{ + if (to == nullptr || from->getType() == to) + { + return from; + } + + llvm::Value* ret = nullptr; + + switch (ct) + { + case eOpConv::SEXT_TRUNC_OR_BITCAST: + { + if (!to->isIntegerTy()) + { + throw GenericError("Invalid combination of conversion method and destination type"); + } + + if (from->getType()->isIntegerTy()) + { + ret = irb.CreateSExtOrTrunc(from, to); + } + else + { + auto size = _module->getDataLayout().getTypeStoreSizeInBits(from->getType()); + auto intTy = irb.getIntNTy(size); + ret = irb.CreateBitCast(from, intTy); + ret = irb.CreateZExtOrTrunc(ret, to); + } + break; + } + case eOpConv::ZEXT_TRUNC_OR_BITCAST: + { + if (!to->isIntegerTy()) + { + throw GenericError("Invalid combination of conversion method and destination type"); + } + + if (from->getType()->isIntegerTy()) + { + ret = irb.CreateZExtOrTrunc(from, to); + } + else + { + auto size = _module->getDataLayout().getTypeStoreSizeInBits(from->getType()); + auto intTy = irb.getIntNTy(size); + ret = irb.CreateBitCast(from, intTy); + ret = irb.CreateZExtOrTrunc(ret, to); + } + break; + } + case eOpConv::FPCAST_OR_BITCAST: + { + if (!to->isFloatingPointTy()) + { + throw GenericError("Invalid combination of conversion method and destination type"); + } + + if (from->getType()->isFloatingPointTy()) + { + ret = irb.CreateFPCast(from, to); + } + else + { + auto isize = _module->getDataLayout().getTypeStoreSizeInBits(from->getType()); + auto dsize = _module->getDataLayout().getTypeStoreSizeInBits(irb.getDoubleTy()); + auto fsize = _module->getDataLayout().getTypeStoreSizeInBits(irb.getFloatTy()); + auto lsize = _module->getDataLayout().getTypeStoreSizeInBits(llvm::Type::getFP128Ty(_module->getContext())); + + if (isize == fsize) + { + from = irb.CreateBitCast(from, irb.getFloatTy()); + } + else if (isize == dsize) + { + from = irb.CreateBitCast(from, irb.getDoubleTy()); + } + else if (isize == lsize) + { + from = irb.CreateBitCast(from, llvm::Type::getFP128Ty(_module->getContext())); + } + else + { + throw GenericError("Unable to create bitcast to floating point type."); + } + + ret = irb.CreateFPCast(from, to); + } + break; + } + case eOpConv::SITOFP_OR_FPCAST: + { + if (!to->isFloatingPointTy()) + { + throw GenericError("Invalid combination of conversion method and destination type"); + } + if (from->getType()->isFloatingPointTy()) + { + ret = irb.CreateFPCast(from, to); + } + else + { + ret = irb.CreateSIToFP(from, to); + } + break; + } + case eOpConv::UITOFP_OR_FPCAST: + { + if (!to->isFloatingPointTy()) + { + throw GenericError("Invalid combination of conversion method and destination type"); + } + if (from->getType()->isFloatingPointTy()) + { + ret = irb.CreateFPCast(from, to); + } + else + { + ret = irb.CreateUIToFP(from, to); + } + break; + } + case eOpConv::NOTHING: + { + ret = from; + break; + } + case eOpConv::THROW: + default: + { + throw GenericError("Unhandled eOpConv type."); + } + } + + return ret; +} + +template +llvm::Type* Capstone2LlvmIrTranslator_impl::_checkTypeConversion( + llvm::IRBuilder<>& irb, + llvm::Type* to, + eOpConv ct) +{ + switch (ct) + { + case eOpConv::ZEXT_TRUNC_OR_BITCAST: + case eOpConv::SEXT_TRUNC_OR_BITCAST: + { + if (!to->isIntegerTy()) + { + auto size = _module->getDataLayout().getTypeStoreSizeInBits(to); + return irb.getIntNTy(size); + } + break; + } + case eOpConv::FPCAST_OR_BITCAST: + case eOpConv::SITOFP_OR_FPCAST: + case eOpConv::UITOFP_OR_FPCAST: + { + if (!to->isFloatingPointTy()) + { + auto flSize = _module->getDataLayout().getTypeStoreSizeInBits( + irb.getFloatTy()); + auto size = _module->getDataLayout().getTypeStoreSizeInBits(to); + if (size <= flSize) + { + return irb.getFloatTy(); + } + + return irb.getDoubleTy(); + } + break; + } + default: + { + return to; + } + } + + return to; +} + +/** + * op0 = __asm_() + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0Fnc( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_UNARY(i, ci, irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + getDefaultType(), + llvm::ArrayRef{}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * __asm_(op0) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_UNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + irb.getVoidTy(), + llvm::ArrayRef{op0->getType()}); + + irb.CreateCall(fnc, llvm::ArrayRef{op0}); +} + +/** + * op0 = __asm_(op0) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_UNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + op0->getType(), + llvm::ArrayRef{op0->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * __asm_(op0, op1) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0Op1( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_BINARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + irb.getVoidTy(), + llvm::ArrayRef{op0->getType(), op1->getType()}); + + irb.CreateCall(fnc, llvm::ArrayRef{op0, op1}); +} + +/** + * op0 = __asm_(op1) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp1( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_BINARY(i, ci, irb); + + op1 = loadOp(ci->operands[1], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + op1->getType(), + llvm::ArrayRef{op1->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op1}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * op0 = __asm_(op0, op1) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0Op1( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_BINARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + op0->getType(), + llvm::ArrayRef{op0->getType(), op1->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * __asm_(op0, op1, op2) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0Op1Op2( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_TERNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + irb.getVoidTy(), + llvm::ArrayRef{ + op0->getType(), + op1->getType(), + op2->getType()}); + + irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2}); +} + +/** + * op0 = __asm_(op1, op2) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp1Op2( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_TERNARY(i, ci, irb); + + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + getDefaultType(), + llvm::ArrayRef{ + op1->getType(), + op2->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op1, op2}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * op0 = __asm_(op0, op1, op2) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0Op1Op2( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_TERNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + op0->getType(), + llvm::ArrayRef{ + op0->getType(), + op1->getType(), + op2->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * __asm_(op0, op1, op2, op3) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmFncOp0Op1Op2Op3( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_QUATERNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + op3 = loadOp(ci->operands[3], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + irb.getVoidTy(), + llvm::ArrayRef{ + op0->getType(), + op1->getType(), + op2->getType(), + op3->getType()}); + + irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2, op3}); +} + +/** + * op0 = __asm_(op1, op2, op3) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp1Op2Op3( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_QUATERNARY(i, ci, irb); + + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + op3 = loadOp(ci->operands[3], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + getDefaultType(), + llvm::ArrayRef{ + op1->getType(), + op2->getType(), + op3->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op1, op2, op3}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * op0 = __asm_(op0, op1, op2, op3) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0FncOp0Op1Op2Op3( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_QUATERNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + op3 = loadOp(ci->operands[3], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + op0->getType(), + llvm::ArrayRef{ + op0->getType(), + op1->getType(), + op2->getType(), + op3->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2, op3}); + + storeOp(ci->operands[0], c, irb); +} + +/** + * op0, op1 = __asm_(op0, op1, op2, op3) + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmOp0Op1FncOp0Op1Op2Op3( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + EXPECT_IS_QUATERNARY(i, ci, irb); + + op0 = loadOp(ci->operands[0], irb); + op1 = loadOp(ci->operands[1], irb); + op2 = loadOp(ci->operands[2], irb); + op3 = loadOp(ci->operands[3], irb); + + llvm::Function* fnc = getPseudoAsmFunction( + i, + llvm::StructType::create(llvm::ArrayRef{ + op0->getType(), + op1->getType()}), + llvm::ArrayRef{ + op0->getType(), + op1->getType(), + op2->getType(), + op3->getType()}); + + auto* c = irb.CreateCall(fnc, llvm::ArrayRef{op0, op1, op2, op3}); + + storeOp(ci->operands[0], irb.CreateExtractValue(c, {0}), irb); + storeOp(ci->operands[1], irb.CreateExtractValue(c, {1}), irb); +} + +/** + * Some architectures do not have this info in operands. + * Return default value: CS_AC_INVALID. + */ +template +uint8_t Capstone2LlvmIrTranslator_impl::getOperandAccess(CInsnOp&) +{ + return CS_AC_INVALID; +} + +/** + * Generate pseudo asm call using information provided by Capstone. + */ +template +void Capstone2LlvmIrTranslator_impl::translatePseudoAsmGeneric( + cs_insn* i, + CInsn* ci, + llvm::IRBuilder<>& irb) +{ + std::vector vals; + std::vector types; + + unsigned writeCnt = 0; + llvm::Type* writeType = getDefaultType(); + bool writesOp = false; + for (std::size_t j = 0; j < ci->op_count; ++j) + { + auto& op = ci->operands[j]; + auto access = getOperandAccess(op); + if (access == CS_AC_INVALID || (access & CS_AC_READ)) + { + auto* o = loadOp(op, irb); + vals.push_back(o); + types.push_back(o->getType()); + } + + if (access & CS_AC_WRITE) + { + writesOp = true; + ++writeCnt; + + if (isOperandRegister(op)) + { + auto* t = getRegisterType(op.reg); + if (writeCnt == 1 || writeType == t) + { + writeType = t; + } + else + { + writeType = getDefaultType(); + } + } + else + { + writeType = getDefaultType(); + } + } + } + + if (vals.empty()) + { + // All registers must be ok, or don't use them at all. + std::vector readRegs; + readRegs.reserve(i->detail->regs_read_count); + for (std::size_t j = 0; j < i->detail->regs_read_count; ++j) + { + auto r = i->detail->regs_read[j]; + if (getRegister(r)) + { + readRegs.push_back(r); + } + else + { + readRegs.clear(); + break; + } + } + + for (auto r : readRegs) + { + auto* op = loadRegister(r, irb); + vals.push_back(op); + types.push_back(op->getType()); + } + } + + auto* retType = writesOp ? writeType : irb.getVoidTy(); + llvm::Function* fnc = getPseudoAsmFunction( + i, + retType, + types); + + auto* c = irb.CreateCall(fnc, vals); + + std::set writtenRegs; + if (retType) + { + for (std::size_t j = 0; j < ci->op_count; ++j) + { + auto& op = ci->operands[j]; + if (getOperandAccess(op) & CS_AC_WRITE) + { + storeOp(op, c, irb); + + if (isOperandRegister(op)) + { + writtenRegs.insert(op.reg); + } + } + } + } + + // All registers must be ok, or don't use them at all. + std::vector writeRegs; + writeRegs.reserve(i->detail->regs_write_count); + for (std::size_t j = 0; j < i->detail->regs_write_count; ++j) + { + auto r = i->detail->regs_write[j]; + if (writtenRegs.count(r)) + { + // silently ignore + } + else if (getRegister(r)) + { + writeRegs.push_back(r); + } + else + { + writeRegs.clear(); + break; + } + } + + for (auto r : writeRegs) + { + llvm::Value* val = retType->isVoidTy() + ? llvm::cast( + llvm::UndefValue::get(getRegisterType(r))) + : llvm::cast(c); + storeRegister(r, val, irb); + } +} + +template +void Capstone2LlvmIrTranslator_impl::throwUnexpectedOperands( + cs_insn* i, + const std::string comment) +{ + if (!isIgnoreUnexpectedOperands()) + { + throw UnexpectedOperandsError(i, comment); + } +} + +template +void Capstone2LlvmIrTranslator_impl::throwUnhandledInstructions( + cs_insn* i, + const std::string comment) +{ + if (!isIgnoreUnhandledInstructions()) + { + throw UnhandledInstructionError(i, comment); + } +} + +template class Capstone2LlvmIrTranslator_impl; +template class Capstone2LlvmIrTranslator_impl; +template class Capstone2LlvmIrTranslator_impl; +template class Capstone2LlvmIrTranslator_impl; +template class Capstone2LlvmIrTranslator_impl; + +} // namespace capstone2llvmir +} // namespace retdec From b52721f50f0fb129e9506378f533fa8e761752dd Mon Sep 17 00:00:00 2001 From: Nitr0-G <120374383+Nitr0-G@users.noreply.github.com> Date: Thu, 27 Apr 2023 21:13:23 +0300 Subject: [PATCH 3/5] Add files via upload --- src/capstone2llvmir/capstone2llvmir_impl.cpp | 49 +++++--------------- 1 file changed, 11 insertions(+), 38 deletions(-) diff --git a/src/capstone2llvmir/capstone2llvmir_impl.cpp b/src/capstone2llvmir/capstone2llvmir_impl.cpp index 0048acc8b..02ecca263 100644 --- a/src/capstone2llvmir/capstone2llvmir_impl.cpp +++ b/src/capstone2llvmir/capstone2llvmir_impl.cpp @@ -237,10 +237,6 @@ Capstone2LlvmIrTranslator_impl::translateOne( llvm::IRBuilder<>& irb) { TranslationResultOne res; - std::vector MPX_INSTRS{ - X86_INS_BNDMK, X86_INS_BNDCL, X86_INS_BNDCU, X86_INS_BNDMOV, X86_INS_BNDLDX, X86_INS_BNDSTX}; - bool MpxInstr = false; - // We want to keep all Capstone instructions -> alloc a new one each time. cs_insn* insn = cs_malloc(_handle); @@ -251,43 +247,17 @@ Capstone2LlvmIrTranslator_impl::translateOne( // TODO: hack, solve better. bool disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - - for (auto& MpxIndexer : MPX_INSTRS) + if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) { - if (insn[0].id == MpxIndexer) - MpxInstr = true; + modifyBasicMode(CS_MODE_MIPS64); + disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); + modifyBasicMode(CS_MODE_MIPS32); } - if (MpxInstr != true) - { - if (!disasmRes && _arch == CS_ARCH_MIPS && _basicMode == CS_MODE_MIPS32) - { - modifyBasicMode(CS_MODE_MIPS64); - disasmRes = cs_disasm_iter(_handle, &bytes, &size, &address, insn); - modifyBasicMode(CS_MODE_MIPS32); - } - - if (disasmRes) - { - auto* a2l = generateSpecialAsm2LlvmInstr(irb, insn); - translateInstruction(insn, irb); - - res.llvmInsn = a2l; - res.capstoneInsn = insn; - res.size = insn->size; - res.branchCall = _branchGenerated; - res.inCondition = _inCondition; - - a = address; - } - else - { - cs_free(insn, 1); - } - } - else + if (disasmRes) { auto* a2l = generateSpecialAsm2LlvmInstr(irb, insn); + translateInstruction(insn, irb); res.llvmInsn = a2l; res.capstoneInsn = insn; @@ -296,9 +266,12 @@ Capstone2LlvmIrTranslator_impl::translateOne( res.inCondition = _inCondition; a = address; - - return res; } + else + { + cs_free(insn, 1); + } + return res; } From 615c283ea9a35cce3ac0019c6078c0b5fe75c98b Mon Sep 17 00:00:00 2001 From: Nitr0-G <120374383+Nitr0-G@users.noreply.github.com> Date: Thu, 27 Apr 2023 21:19:17 +0300 Subject: [PATCH 4/5] Intel MPX support Skipping all MPX instructions has been added in order to eliminate bugs caused on these Issues (https://github.com/avast/retdec/issues/1148 https://github.com/avast/retdec/issues/1135) Proof that these bugs have been fixed, you can find in the same Issue(https://github.com/avast/retdec/issues/1148 https://github.com/avast/retdec/issues/1135) Intel MPX is a dead technology that has not been supported by the Linux kernel since 2020(proof: https://www.phoronix.com/news/Intel-MPX-Is-Dead). It was only in the Skylake and Intel Goldmont(atom) architecture, consider all current processors do not support this technology. Zydis & capstone mistakenly disassembles instructions added to Intel MPX(Intel MPX adds 7 new instructions, as well as BND0-3 registers in x64 and x32 mode for more information, see here(https://intel-mpx.github.io/design/ )), a tool like Hiew also does not disassemble instructions of Intel MPX (https://fpic.in/VQ9yfJ1) Added 6 new instructions(MPX) that translates to NOP --- src/capstone2llvmir/x86/x86_init.cpp | 3908 +++++++++++++------------- 1 file changed, 1957 insertions(+), 1951 deletions(-) diff --git a/src/capstone2llvmir/x86/x86_init.cpp b/src/capstone2llvmir/x86/x86_init.cpp index 15637452a..0bdefce91 100644 --- a/src/capstone2llvmir/x86/x86_init.cpp +++ b/src/capstone2llvmir/x86/x86_init.cpp @@ -1,1951 +1,1957 @@ -/** - * @file src/capstone2llvmir/x86/x86_init.cpp - * @brief Initializations for X86 implementation of @c Capstone2LlvmIrTranslator. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include "capstone2llvmir/x86/x86_impl.h" - -namespace retdec { -namespace capstone2llvmir { - -// -//============================================================================== -// Pure virtual methods from Capstone2LlvmIrTranslator_impl -//============================================================================== -// - -void Capstone2LlvmIrTranslatorX86_impl::initializeArchSpecific() -{ - initializeRegistersParentMap(); -} - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegNameMap() -{ - std::map r2n = - { - // x86_reg_rflags - // - {X86_REG_CF, "cf"}, - {X86_REG_PF, "pf"}, - {X86_REG_AF, "az"}, - {X86_REG_ZF, "zf"}, - {X86_REG_SF, "sf"}, - {X86_REG_TF, "tf"}, - {X86_REG_IF, "if"}, - {X86_REG_DF, "df"}, - {X86_REG_OF, "of"}, - {X86_REG_IOPL, "iopl"}, - {X86_REG_NT, "nt"}, - {X86_REG_RF, "rf"}, - {X86_REG_VM, "vm"}, - {X86_REG_AC, "ac"}, - {X86_REG_VIF, "vif"}, - {X86_REG_VIP, "vip"}, - {X86_REG_ID, "id"}, - - // x87_reg_status - // - {X87_REG_IE, "fpu_stat_IE"}, - {X87_REG_DE, "fpu_stat_DE"}, - {X87_REG_ZE, "fpu_stat_ZE"}, - {X87_REG_OE, "fpu_stat_OE"}, - {X87_REG_UE, "fpu_stat_UE"}, - {X87_REG_PE, "fpu_stat_PE"}, - {X87_REG_SF, "fpu_stat_SF"}, - {X87_REG_ES, "fpu_stat_ES"}, - {X87_REG_C0, "fpu_stat_C0"}, - {X87_REG_C1, "fpu_stat_C1"}, - {X87_REG_C2, "fpu_stat_C2"}, - {X87_REG_C3, "fpu_stat_C3"}, - {X87_REG_TOP, "fpu_stat_TOP"}, - {X87_REG_B, "fpu_stat_B"}, - - // x87_reg_control - // - {X87_REG_IM, "fpu_control_IM"}, - {X87_REG_DM, "fpu_control_DM"}, - {X87_REG_ZM, "fpu_control_ZM"}, - {X87_REG_OM, "fpu_control_OM"}, - {X87_REG_UM, "fpu_control_UM"}, - {X87_REG_PM, "fpu_control_PM"}, - {X87_REG_PC, "fpu_control_PC"}, - {X87_REG_RC, "fpu_control_RC"}, - {X87_REG_X, "fpu_control_X"}, - - // FPU data registers - // They are named as ST(X) in Capstone, which is not good for us. - // - {X86_REG_ST0, "st0"}, - {X86_REG_ST1, "st1"}, - {X86_REG_ST2, "st2"}, - {X86_REG_ST3, "st3"}, - {X86_REG_ST4, "st4"}, - {X86_REG_ST5, "st5"}, - {X86_REG_ST6, "st6"}, - {X86_REG_ST7, "st7"}, - }; - - _reg2name = std::move(r2n); -} - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegTypeMap() -{ - auto* i1 = llvm::IntegerType::getInt1Ty(_module->getContext()); - auto* i2 = llvm::IntegerType::getIntNTy(_module->getContext(), 2); - auto* i3 = llvm::IntegerType::getIntNTy(_module->getContext(), 3); - auto* i8 = llvm::IntegerType::getInt8Ty(_module->getContext()); - auto* i16 = llvm::IntegerType::getInt16Ty(_module->getContext()); - auto* i32 = llvm::IntegerType::getInt32Ty(_module->getContext()); - auto* i64 = llvm::IntegerType::getInt64Ty(_module->getContext()); - auto* i128 = llvm::IntegerType::getInt128Ty(_module->getContext()); - auto* i256 = llvm::IntegerType::getIntNTy(_module->getContext(), 256); - auto* i512 = llvm::IntegerType::getIntNTy(_module->getContext(), 512); - auto* fp64 = llvm::IntegerType::getDoubleTy(_module->getContext()); - auto* fp80 = llvm::IntegerType::getX86_FP80Ty(_module->getContext()); - - auto* defTy = _origBasicMode == CS_MODE_64 ? i64 : i32; - - std::map r2t = - { - // x86_reg - // - {X86_REG_AH, i8}, - {X86_REG_AL, i8}, - {X86_REG_CH, i8}, - {X86_REG_CL, i8}, - {X86_REG_DH, i8}, - {X86_REG_DL, i8}, - {X86_REG_BH, i8}, - {X86_REG_BL, i8}, - {X86_REG_SPL, i8}, - {X86_REG_BPL, i8}, - {X86_REG_DIL, i8}, - {X86_REG_SIL, i8}, - {X86_REG_R8B, i8}, - {X86_REG_R9B, i8}, - {X86_REG_R10B, i8}, - {X86_REG_R11B, i8}, - {X86_REG_R12B, i8}, - {X86_REG_R13B, i8}, - {X86_REG_R14B, i8}, - {X86_REG_R15B, i8}, - - {X86_REG_AX, i16}, - {X86_REG_CX, i16}, - {X86_REG_DX, i16}, - {X86_REG_BP, i16}, - {X86_REG_BX, i16}, - {X86_REG_DI, i16}, - {X86_REG_SP, i16}, - {X86_REG_SI, i16}, - {X86_REG_SS, i16}, - {X86_REG_CS, i16}, - {X86_REG_DS, i16}, - {X86_REG_ES, i16}, - {X86_REG_FS, i16}, - {X86_REG_GS, i16}, - {X86_REG_R8W, i16}, - {X86_REG_R9W, i16}, - {X86_REG_R10W, i16}, - {X86_REG_R11W, i16}, - {X86_REG_R12W, i16}, - {X86_REG_R13W, i16}, - {X86_REG_R14W, i16}, - {X86_REG_R15W, i16}, - {X86_REG_IP, i16}, - - {X86_REG_EAX, i32}, - {X86_REG_EBP, i32}, - {X86_REG_EBX, i32}, - {X86_REG_ECX, i32}, - {X86_REG_EDI, i32}, - {X86_REG_EDX, i32}, - {X86_REG_ESI, i32}, - {X86_REG_ESP, i32}, - {X86_REG_R8D, i32}, - {X86_REG_R9D, i32}, - {X86_REG_R10D, i32}, - {X86_REG_R11D, i32}, - {X86_REG_R12D, i32}, - {X86_REG_R13D, i32}, - {X86_REG_R14D, i32}, - {X86_REG_R15D, i32}, - {X86_REG_EIP, i32}, - {X86_REG_EIZ, i32}, - - {X86_REG_RAX, i64}, - {X86_REG_RBP, i64}, - {X86_REG_RBX, i64}, - {X86_REG_RCX, i64}, - {X86_REG_RDI, i64}, - {X86_REG_RDX, i64}, - {X86_REG_RIP, i64}, - {X86_REG_RIZ, i64}, - {X86_REG_RSI, i64}, - {X86_REG_RSP, i64}, - {X86_REG_R8, i64}, - {X86_REG_R9, i64}, - {X86_REG_R10, i64}, - {X86_REG_R11, i64}, - {X86_REG_R12, i64}, - {X86_REG_R13, i64}, - {X86_REG_R14, i64}, - {X86_REG_R15, i64}, - - {X86_REG_ST0, fp80}, - {X86_REG_ST1, fp80}, - {X86_REG_ST2, fp80}, - {X86_REG_ST3, fp80}, - {X86_REG_ST4, fp80}, - {X86_REG_ST5, fp80}, - {X86_REG_ST6, fp80}, - {X86_REG_ST7, fp80}, - - {X86_REG_FP0, fp64}, - {X86_REG_FP1, fp64}, - {X86_REG_FP2, fp64}, - {X86_REG_FP3, fp64}, - {X86_REG_FP4, fp64}, - {X86_REG_FP5, fp64}, - {X86_REG_FP6, fp64}, - {X86_REG_FP7, fp64}, - - {X86_REG_EFLAGS, defTy}, - {X86_REG_DR0, defTy}, - {X86_REG_DR1, defTy}, - {X86_REG_DR2, defTy}, - {X86_REG_DR3, defTy}, - {X86_REG_DR4, defTy}, - {X86_REG_DR5, defTy}, - {X86_REG_DR6, defTy}, - {X86_REG_DR7, defTy}, - {X86_REG_DR8, defTy}, - {X86_REG_DR9, defTy}, - {X86_REG_DR10, defTy}, - {X86_REG_DR11, defTy}, - {X86_REG_DR12, defTy}, - {X86_REG_DR13, defTy}, - {X86_REG_DR14, defTy}, - {X86_REG_DR15, defTy}, - - {X86_REG_CR0, defTy}, - {X86_REG_CR1, defTy}, - {X86_REG_CR2, defTy}, - {X86_REG_CR3, defTy}, - {X86_REG_CR4, defTy}, - {X86_REG_CR5, defTy}, - {X86_REG_CR6, defTy}, - {X86_REG_CR7, defTy}, - {X86_REG_CR8, defTy}, - {X86_REG_CR9, defTy}, - {X86_REG_CR10, defTy}, - {X86_REG_CR11, defTy}, - {X86_REG_CR12, defTy}, - {X86_REG_CR13, defTy}, - {X86_REG_CR14, defTy}, - {X86_REG_CR15, defTy}, - - {X86_REG_FPSW, defTy}, - - // opmask registers (AVX-512) - {X86_REG_K0, i64}, - {X86_REG_K1, i64}, - {X86_REG_K2, i64}, - {X86_REG_K3, i64}, - {X86_REG_K4, i64}, - {X86_REG_K5, i64}, - {X86_REG_K6, i64}, - {X86_REG_K7, i64}, - - // MMX - {X86_REG_MM0, i64}, - {X86_REG_MM1, i64}, - {X86_REG_MM2, i64}, - {X86_REG_MM3, i64}, - {X86_REG_MM4, i64}, - {X86_REG_MM5, i64}, - {X86_REG_MM6, i64}, - {X86_REG_MM7, i64}, - - // XMM - {X86_REG_XMM0, i128}, - {X86_REG_XMM1, i128}, - {X86_REG_XMM2, i128}, - {X86_REG_XMM3, i128}, - {X86_REG_XMM4, i128}, - {X86_REG_XMM5, i128}, - {X86_REG_XMM6, i128}, - {X86_REG_XMM7, i128}, - {X86_REG_XMM8, i128}, - {X86_REG_XMM9, i128}, - {X86_REG_XMM10, i128}, - {X86_REG_XMM11, i128}, - {X86_REG_XMM12, i128}, - {X86_REG_XMM13, i128}, - {X86_REG_XMM14, i128}, - {X86_REG_XMM15, i128}, - {X86_REG_XMM16, i128}, - {X86_REG_XMM17, i128}, - {X86_REG_XMM18, i128}, - {X86_REG_XMM19, i128}, - {X86_REG_XMM20, i128}, - {X86_REG_XMM21, i128}, - {X86_REG_XMM22, i128}, - {X86_REG_XMM23, i128}, - {X86_REG_XMM24, i128}, - {X86_REG_XMM25, i128}, - {X86_REG_XMM26, i128}, - {X86_REG_XMM27, i128}, - {X86_REG_XMM28, i128}, - {X86_REG_XMM29, i128}, - {X86_REG_XMM30, i128}, - {X86_REG_XMM31, i128}, - - // YMM - {X86_REG_YMM0, i256}, - {X86_REG_YMM1, i256}, - {X86_REG_YMM2, i256}, - {X86_REG_YMM3, i256}, - {X86_REG_YMM4, i256}, - {X86_REG_YMM5, i256}, - {X86_REG_YMM6, i256}, - {X86_REG_YMM7, i256}, - {X86_REG_YMM8, i256}, - {X86_REG_YMM9, i256}, - {X86_REG_YMM10, i256}, - {X86_REG_YMM11, i256}, - {X86_REG_YMM12, i256}, - {X86_REG_YMM13, i256}, - {X86_REG_YMM14, i256}, - {X86_REG_YMM15, i256}, - {X86_REG_YMM16, i256}, - {X86_REG_YMM17, i256}, - {X86_REG_YMM18, i256}, - {X86_REG_YMM19, i256}, - {X86_REG_YMM20, i256}, - {X86_REG_YMM21, i256}, - {X86_REG_YMM22, i256}, - {X86_REG_YMM23, i256}, - {X86_REG_YMM24, i256}, - {X86_REG_YMM25, i256}, - {X86_REG_YMM26, i256}, - {X86_REG_YMM27, i256}, - {X86_REG_YMM28, i256}, - {X86_REG_YMM29, i256}, - {X86_REG_YMM30, i256}, - {X86_REG_YMM31, i256}, - - // ZMM - {X86_REG_ZMM0, i512}, - {X86_REG_ZMM1, i512}, - {X86_REG_ZMM2, i512}, - {X86_REG_ZMM3, i512}, - {X86_REG_ZMM4, i512}, - {X86_REG_ZMM5, i512}, - {X86_REG_ZMM6, i512}, - {X86_REG_ZMM7, i512}, - {X86_REG_ZMM8, i512}, - {X86_REG_ZMM9, i512}, - {X86_REG_ZMM10, i512}, - {X86_REG_ZMM11, i512}, - {X86_REG_ZMM12, i512}, - {X86_REG_ZMM13, i512}, - {X86_REG_ZMM14, i512}, - {X86_REG_ZMM15, i512}, - {X86_REG_ZMM16, i512}, - {X86_REG_ZMM17, i512}, - {X86_REG_ZMM18, i512}, - {X86_REG_ZMM19, i512}, - {X86_REG_ZMM20, i512}, - {X86_REG_ZMM21, i512}, - {X86_REG_ZMM22, i512}, - {X86_REG_ZMM23, i512}, - {X86_REG_ZMM24, i512}, - {X86_REG_ZMM25, i512}, - {X86_REG_ZMM26, i512}, - {X86_REG_ZMM27, i512}, - {X86_REG_ZMM28, i512}, - {X86_REG_ZMM29, i512}, - {X86_REG_ZMM30, i512}, - {X86_REG_ZMM31, i512}, - - // x86_reg_rflags - // - {X86_REG_CF, i1}, - {X86_REG_PF, i1}, - {X86_REG_AF, i1}, - {X86_REG_ZF, i1}, - {X86_REG_SF, i1}, - {X86_REG_TF, i1}, - {X86_REG_IF, i1}, - {X86_REG_DF, i1}, - {X86_REG_OF, i1}, - {X86_REG_IOPL, i2}, - {X86_REG_NT, i1}, - {X86_REG_RF, i1}, - {X86_REG_VM, i1}, - {X86_REG_AC, i1}, - {X86_REG_VIF, i1}, - {X86_REG_VIP, i1}, - {X86_REG_ID, i1}, - - // x87_reg_status - // - {X87_REG_IE, i1}, - {X87_REG_DE, i1}, - {X87_REG_ZE, i1}, - {X87_REG_OE, i1}, - {X87_REG_UE, i1}, - {X87_REG_PE, i1}, - {X87_REG_SF, i1}, - {X87_REG_ES, i1}, - {X87_REG_C0, i1}, - {X87_REG_C1, i1}, - {X87_REG_C2, i1}, - {X87_REG_C3, i1}, - {X87_REG_TOP, i3}, - {X87_REG_B, i1}, - - // x87_reg_control - // - {X87_REG_IM, i1}, - {X87_REG_DM, i1}, - {X87_REG_ZM, i1}, - {X87_REG_OM, i1}, - {X87_REG_UM, i1}, - {X87_REG_PM, i1}, - {X87_REG_PC, i2}, - {X87_REG_RC, i2}, - {X87_REG_X, i1}, - }; - - _reg2type = std::move(r2t); -} - -void Capstone2LlvmIrTranslatorX86_impl::initializePseudoCallInstructionIDs() -{ - _callInsnIds = - { - X86_INS_CALL, - X86_INS_LCALL, - }; - - _returnInsnIds = - { - X86_INS_RET, - X86_INS_RETF, - X86_INS_RETFQ - }; - - _branchInsnIds = - { - X86_INS_JMP, - X86_INS_LJMP, - }; - - _condBranchInsnIds = - { - X86_INS_JCXZ, - X86_INS_JECXZ, - X86_INS_JRCXZ, - // - X86_INS_LOOP, - X86_INS_LOOPE, - X86_INS_LOOPNE, - // - X86_INS_JAE, - X86_INS_JA, - X86_INS_JBE, - X86_INS_JB, - X86_INS_JE, - X86_INS_JGE, - X86_INS_JG, - X86_INS_JLE, - X86_INS_JL, - X86_INS_JNE, - X86_INS_JNO, - X86_INS_JNP, - X86_INS_JNS, - X86_INS_JO, - X86_INS_JP, - X86_INS_JS, - }; - - _controlFlowInsnIds = - { - // Currently, all instructions can be categorized based on their - // IDs alone. - }; -} - -// -//============================================================================== -// x86-specific methods. -//============================================================================== -// - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMapToOther( - const std::vector& rs, - x86_reg other) -{ - for (auto r : rs) - { - if (r >= _reg2parentMap.size()) - { - throw GenericError("Register out of range."); - } - _reg2parentMap[r] = other; - } -} - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap() -{ - switch (_origBasicMode) - { - case CS_MODE_16: initializeRegistersParentMap16(); break; - case CS_MODE_32: initializeRegistersParentMap32(); break; - case CS_MODE_64: initializeRegistersParentMap64(); break; - default: - { - throw GenericError("Unhandled mode in " - "initializeRegistersParentMap()."); - break; - } - } -} - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap16() -{ - // Last element in vector is its own parent. - std::vector> rss = - { - {X86_REG_AH, X86_REG_AL, X86_REG_AX}, - {X86_REG_CH, X86_REG_CL, X86_REG_CX}, - {X86_REG_DH, X86_REG_DL, X86_REG_DX}, - {X86_REG_BH, X86_REG_BL, X86_REG_BX}, - {X86_REG_SPL, X86_REG_SP}, - {X86_REG_BPL, X86_REG_BP}, - {X86_REG_SIL, X86_REG_SI}, - {X86_REG_DIL, X86_REG_DI}, - {X86_REG_IP}, - }; - - for (std::vector& rs : rss) - { - initializeRegistersParentMapToOther(rs, rs.back()); - } -} - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap32() -{ - // Last element in vector is its own parent. - std::vector> rss = - { - {X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_EAX}, - {X86_REG_CH, X86_REG_CL, X86_REG_CX, X86_REG_ECX}, - {X86_REG_DH, X86_REG_DL, X86_REG_DX, X86_REG_EDX}, - {X86_REG_BH, X86_REG_BL, X86_REG_BX, X86_REG_EBX}, - {X86_REG_SPL, X86_REG_SP, X86_REG_ESP}, - {X86_REG_BPL, X86_REG_BP, X86_REG_EBP}, - {X86_REG_SIL, X86_REG_SI, X86_REG_ESI}, - {X86_REG_DIL, X86_REG_DI, X86_REG_EDI}, - {X86_REG_IP, X86_REG_EIP}, - {X86_REG_EIZ}, - }; - - for (std::vector& rs : rss) - { - initializeRegistersParentMapToOther(rs, rs.back()); - } -} - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap64() -{ - // Last element in vector is its own parent. - std::vector> rss = - { - {X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_EAX, X86_REG_RAX}, - {X86_REG_CH, X86_REG_CL, X86_REG_CX, X86_REG_ECX, X86_REG_RCX}, - {X86_REG_DH, X86_REG_DL, X86_REG_DX, X86_REG_EDX, X86_REG_RDX}, - {X86_REG_BH, X86_REG_BL, X86_REG_BX, X86_REG_EBX, X86_REG_RBX}, - {X86_REG_SPL, X86_REG_SP, X86_REG_ESP, X86_REG_RSP}, - {X86_REG_BPL, X86_REG_BP, X86_REG_EBP, X86_REG_RBP}, - {X86_REG_SIL, X86_REG_SI, X86_REG_ESI, X86_REG_RSI}, - {X86_REG_DIL, X86_REG_DI, X86_REG_EDI, X86_REG_RDI}, - {X86_REG_IP, X86_REG_EIP, X86_REG_RIP}, - {X86_REG_EIZ, X86_REG_RIZ}, - {X86_REG_R8B, X86_REG_R8W, X86_REG_R8D, X86_REG_R8}, - {X86_REG_R9B, X86_REG_R9W, X86_REG_R9D, X86_REG_R9}, - {X86_REG_R10B, X86_REG_R10W, X86_REG_R10D, X86_REG_R10}, - {X86_REG_R11B, X86_REG_R11W, X86_REG_R11D, X86_REG_R11}, - {X86_REG_R12B, X86_REG_R12W, X86_REG_R12D, X86_REG_R12}, - {X86_REG_R13B, X86_REG_R13W, X86_REG_R13D, X86_REG_R13}, - {X86_REG_R14B, X86_REG_R14W, X86_REG_R14D, X86_REG_R14}, - {X86_REG_R15B, X86_REG_R15W, X86_REG_R15D, X86_REG_R15} - }; - - for (std::vector& rs : rss) - { - initializeRegistersParentMapToOther(rs, rs.back()); - } -} - -// -//============================================================================== -// Instruction translation map initialization. -//============================================================================== -// - -std::map< - std::size_t, - void (Capstone2LlvmIrTranslatorX86_impl::*)( - cs_insn* i, - cs_x86*, - llvm::IRBuilder<>&)> -Capstone2LlvmIrTranslatorX86_impl::_i2fm = -{ - {X86_INS_INVALID, nullptr}, - - {X86_INS_AAA, &Capstone2LlvmIrTranslatorX86_impl::translateAaa}, - {X86_INS_AAD, &Capstone2LlvmIrTranslatorX86_impl::translateAad}, - {X86_INS_AAM, &Capstone2LlvmIrTranslatorX86_impl::translateAam}, - {X86_INS_AAS, &Capstone2LlvmIrTranslatorX86_impl::translateAaa}, - {X86_INS_FABS, &Capstone2LlvmIrTranslatorX86_impl::translateFabs}, - {X86_INS_ADC, &Capstone2LlvmIrTranslatorX86_impl::translateAdc}, - {X86_INS_ADCX, &Capstone2LlvmIrTranslatorX86_impl::translateAdc}, - {X86_INS_ADD, &Capstone2LlvmIrTranslatorX86_impl::translateAdd}, - {X86_INS_ADDPD, nullptr}, - {X86_INS_ADDPS, nullptr}, - {X86_INS_ADDSD, nullptr}, - {X86_INS_ADDSS, nullptr}, - {X86_INS_ADDSUBPD, nullptr}, - {X86_INS_ADDSUBPS, nullptr}, - {X86_INS_FADD, &Capstone2LlvmIrTranslatorX86_impl::translateFadd}, - {X86_INS_FIADD, &Capstone2LlvmIrTranslatorX86_impl::translateFadd}, - {X86_INS_ADOX, &Capstone2LlvmIrTranslatorX86_impl::translateAdc}, - {X86_INS_AESDECLAST, nullptr}, - {X86_INS_AESDEC, nullptr}, - {X86_INS_AESENCLAST, nullptr}, - {X86_INS_AESENC, nullptr}, - {X86_INS_AESIMC, nullptr}, - {X86_INS_AESKEYGENASSIST, nullptr}, - {X86_INS_AND, &Capstone2LlvmIrTranslatorX86_impl::translateAnd}, - {X86_INS_ANDN, nullptr}, - {X86_INS_ANDNPD, nullptr}, - {X86_INS_ANDNPS, nullptr}, - {X86_INS_ANDPD, nullptr}, - {X86_INS_ANDPS, nullptr}, - {X86_INS_ARPL, nullptr}, - {X86_INS_BEXTR, nullptr}, - {X86_INS_BLCFILL, nullptr}, - {X86_INS_BLCI, nullptr}, - {X86_INS_BLCIC, nullptr}, - {X86_INS_BLCMSK, nullptr}, - {X86_INS_BLCS, nullptr}, - {X86_INS_BLENDPD, nullptr}, - {X86_INS_BLENDPS, nullptr}, - {X86_INS_BLENDVPD, nullptr}, - {X86_INS_BLENDVPS, nullptr}, - {X86_INS_BLSFILL, nullptr}, - {X86_INS_BLSI, nullptr}, - {X86_INS_BLSIC, nullptr}, - {X86_INS_BLSMSK, nullptr}, - {X86_INS_BLSR, nullptr}, - {X86_INS_BOUND, nullptr}, - {X86_INS_BSF, &Capstone2LlvmIrTranslatorX86_impl::translateBsf}, - {X86_INS_BSR, &Capstone2LlvmIrTranslatorX86_impl::translateBsf}, - {X86_INS_BSWAP, &Capstone2LlvmIrTranslatorX86_impl::translateBswap}, - {X86_INS_BT, &Capstone2LlvmIrTranslatorX86_impl::translateBt}, - {X86_INS_BTC, &Capstone2LlvmIrTranslatorX86_impl::translateBtc}, - {X86_INS_BTR, &Capstone2LlvmIrTranslatorX86_impl::translateBtr}, - {X86_INS_BTS, &Capstone2LlvmIrTranslatorX86_impl::translateBts}, - {X86_INS_BZHI, nullptr}, - {X86_INS_CALL, &Capstone2LlvmIrTranslatorX86_impl::translateCall}, - {X86_INS_CBW, &Capstone2LlvmIrTranslatorX86_impl::translateCbw}, - {X86_INS_CDQ, &Capstone2LlvmIrTranslatorX86_impl::translateCdq}, - {X86_INS_CDQE, &Capstone2LlvmIrTranslatorX86_impl::translateCdqe}, - {X86_INS_FCHS, &Capstone2LlvmIrTranslatorX86_impl::translateFchs}, - {X86_INS_CLAC, nullptr}, - {X86_INS_CLC, &Capstone2LlvmIrTranslatorX86_impl::translateClc}, - {X86_INS_CLD, &Capstone2LlvmIrTranslatorX86_impl::translateCld}, - {X86_INS_CLFLUSH, nullptr}, - {X86_INS_CLFLUSHOPT, nullptr}, - {X86_INS_CLGI, nullptr}, - {X86_INS_CLI, &Capstone2LlvmIrTranslatorX86_impl::translateCli}, - {X86_INS_CLTS, nullptr}, - {X86_INS_CLWB, nullptr}, - {X86_INS_CMC, &Capstone2LlvmIrTranslatorX86_impl::translateCmc}, - {X86_INS_CMOVA, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVAE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVB, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVBE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_FCMOVBE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_FCMOVB, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_CMOVE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_FCMOVE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_CMOVG, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVGE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVL, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVLE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_FCMOVNBE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_FCMOVNB, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_CMOVNE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_FCMOVNE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_CMOVNO, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVNP, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_FCMOVNU, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_CMOVNS, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVO, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVP, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_FCMOVU, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_CMOVS, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMP, &Capstone2LlvmIrTranslatorX86_impl::translateSub}, - {X86_INS_CMPSB, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, - {X86_INS_CMPSQ, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, - {X86_INS_CMPSW, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, - {X86_INS_CMPXCHG16B, &Capstone2LlvmIrTranslatorX86_impl::translateCmpxchg16b}, - {X86_INS_CMPXCHG, &Capstone2LlvmIrTranslatorX86_impl::translateCmpxchg}, - {X86_INS_CMPXCHG8B, &Capstone2LlvmIrTranslatorX86_impl::translateCmpxchg8b}, - {X86_INS_COMISD, nullptr}, - {X86_INS_COMISS, nullptr}, - {X86_INS_FCOMP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FCOMPI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FCOMI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FCOM, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FCOS, &Capstone2LlvmIrTranslatorX86_impl::translateFcos}, - {X86_INS_CPUID, &Capstone2LlvmIrTranslatorX86_impl::translateCpuid}, - {X86_INS_CQO, &Capstone2LlvmIrTranslatorX86_impl::translateCqo}, - {X86_INS_CRC32, nullptr}, - {X86_INS_CVTDQ2PD, nullptr}, - {X86_INS_CVTDQ2PS, nullptr}, - {X86_INS_CVTPD2DQ, nullptr}, - {X86_INS_CVTPD2PS, nullptr}, - {X86_INS_CVTPS2DQ, nullptr}, - {X86_INS_CVTPS2PD, nullptr}, - {X86_INS_CVTSD2SI, nullptr}, - {X86_INS_CVTSD2SS, nullptr}, - {X86_INS_CVTSI2SD, nullptr}, - {X86_INS_CVTSI2SS, nullptr}, - {X86_INS_CVTSS2SD, nullptr}, - {X86_INS_CVTSS2SI, nullptr}, - {X86_INS_CVTTPD2DQ, nullptr}, - {X86_INS_CVTTPS2DQ, nullptr}, - {X86_INS_CVTTSD2SI, nullptr}, - {X86_INS_CVTTSS2SI, nullptr}, - {X86_INS_CWD, &Capstone2LlvmIrTranslatorX86_impl::translateCwd}, - {X86_INS_CWDE, &Capstone2LlvmIrTranslatorX86_impl::translateCwde}, - {X86_INS_DAA, &Capstone2LlvmIrTranslatorX86_impl::translateDaaDas}, - {X86_INS_DAS, &Capstone2LlvmIrTranslatorX86_impl::translateDaaDas}, - {X86_INS_DATA16, nullptr}, - {X86_INS_DEC, &Capstone2LlvmIrTranslatorX86_impl::translateDec}, - {X86_INS_DIV, &Capstone2LlvmIrTranslatorX86_impl::translateDiv}, - {X86_INS_DIVPD, nullptr}, - {X86_INS_DIVPS, nullptr}, - {X86_INS_FDIVR, &Capstone2LlvmIrTranslatorX86_impl::translateFdivr}, - {X86_INS_FIDIVR, &Capstone2LlvmIrTranslatorX86_impl::translateFdivr}, - {X86_INS_FDIVRP, &Capstone2LlvmIrTranslatorX86_impl::translateFdivr}, - {X86_INS_DIVSD, nullptr}, - {X86_INS_DIVSS, nullptr}, - {X86_INS_FDIV, &Capstone2LlvmIrTranslatorX86_impl::translateFdiv}, - {X86_INS_FIDIV, &Capstone2LlvmIrTranslatorX86_impl::translateFdiv}, - {X86_INS_FDIVP, &Capstone2LlvmIrTranslatorX86_impl::translateFdiv}, - {X86_INS_DPPD, nullptr}, - {X86_INS_DPPS, nullptr}, - {X86_INS_RET, &Capstone2LlvmIrTranslatorX86_impl::translateRet}, - {X86_INS_ENCLS, nullptr}, - {X86_INS_ENCLU, nullptr}, - {X86_INS_ENTER, &Capstone2LlvmIrTranslatorX86_impl::translateEnter}, - {X86_INS_EXTRACTPS, nullptr}, - {X86_INS_EXTRQ, nullptr}, - {X86_INS_F2XM1, &Capstone2LlvmIrTranslatorX86_impl::translateF2xm1}, - {X86_INS_LCALL, &Capstone2LlvmIrTranslatorX86_impl::translateLcall}, - {X86_INS_LJMP, &Capstone2LlvmIrTranslatorX86_impl::translateLjmp}, - {X86_INS_FBLD, &Capstone2LlvmIrTranslatorX86_impl::translateFbld}, - {X86_INS_FBSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFbstp}, - {X86_INS_FCOMPP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FDECSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFdecstp}, - {X86_INS_FEMMS, nullptr}, - {X86_INS_FFREE, &Capstone2LlvmIrTranslatorX86_impl::translateFfree}, - {X86_INS_FICOM, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FICOMP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FINCSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFincstp}, - {X86_INS_FLDCW, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_FLDENV, &Capstone2LlvmIrTranslatorX86_impl::translatePseudoAsmFncOp0}, - {X86_INS_FLDL2E, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FLDL2T, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FLDLG2, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FLDLN2, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FLDPI, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FNCLEX, &Capstone2LlvmIrTranslatorX86_impl::translateFnclex}, - {X86_INS_FNINIT, &Capstone2LlvmIrTranslatorX86_impl::translateFninit}, - {X86_INS_FNOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_FNSTCW, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_FNSTSW, &Capstone2LlvmIrTranslatorX86_impl::translateFnstsw}, - {X86_INS_FPATAN, &Capstone2LlvmIrTranslatorX86_impl::translateFatan}, - {X86_INS_FPREM, &Capstone2LlvmIrTranslatorX86_impl::translateFprem}, - {X86_INS_FPREM1, &Capstone2LlvmIrTranslatorX86_impl::translateFprem}, - {X86_INS_FPTAN, &Capstone2LlvmIrTranslatorX86_impl::translateFtan}, - {X86_INS_FFREEP, nullptr}, - {X86_INS_FRNDINT, &Capstone2LlvmIrTranslatorX86_impl::translateFrndint}, - {X86_INS_FRSTOR, &Capstone2LlvmIrTranslatorX86_impl::translateFrstor}, - {X86_INS_FNSAVE, &Capstone2LlvmIrTranslatorX86_impl::translateFnsave}, - {X86_INS_FSCALE, &Capstone2LlvmIrTranslatorX86_impl::translateFscale}, - {X86_INS_FSETPM, nullptr}, - {X86_INS_FSINCOS, &Capstone2LlvmIrTranslatorX86_impl::translateFsincos}, - {X86_INS_FNSTENV, &Capstone2LlvmIrTranslatorX86_impl::translateFnstenv}, - {X86_INS_FXAM, &Capstone2LlvmIrTranslatorX86_impl::translateFxam}, - {X86_INS_FXRSTOR, &Capstone2LlvmIrTranslatorX86_impl::translateFxstor}, - {X86_INS_FXRSTOR64, &Capstone2LlvmIrTranslatorX86_impl::translateFxstor}, - {X86_INS_FXSAVE, &Capstone2LlvmIrTranslatorX86_impl::translateFxsave}, - {X86_INS_FXSAVE64, &Capstone2LlvmIrTranslatorX86_impl::translateFxsave}, - {X86_INS_FXTRACT, &Capstone2LlvmIrTranslatorX86_impl::translateFxtract}, - {X86_INS_FYL2X, &Capstone2LlvmIrTranslatorX86_impl::translateFyl2x}, - {X86_INS_FYL2XP1, &Capstone2LlvmIrTranslatorX86_impl::translateFyl2x}, - {X86_INS_MOVAPD, nullptr}, - {X86_INS_MOVAPS, nullptr}, - {X86_INS_ORPD, nullptr}, - {X86_INS_ORPS, nullptr}, - {X86_INS_VMOVAPD, nullptr}, - {X86_INS_VMOVAPS, nullptr}, - {X86_INS_XORPD, nullptr}, - {X86_INS_XORPS, nullptr}, - {X86_INS_GETSEC, nullptr}, - {X86_INS_HADDPD, nullptr}, - {X86_INS_HADDPS, nullptr}, - {X86_INS_HLT, nullptr}, - {X86_INS_HSUBPD, nullptr}, - {X86_INS_HSUBPS, nullptr}, - {X86_INS_IDIV, &Capstone2LlvmIrTranslatorX86_impl::translateDiv}, - {X86_INS_FILD, &Capstone2LlvmIrTranslatorX86_impl::translateFld}, - {X86_INS_IMUL, &Capstone2LlvmIrTranslatorX86_impl::translateImul}, - {X86_INS_IN, nullptr}, - {X86_INS_INC, &Capstone2LlvmIrTranslatorX86_impl::translateInc}, - {X86_INS_INSB, &Capstone2LlvmIrTranslatorX86_impl::translateIns}, - {X86_INS_INSERTPS, nullptr}, - {X86_INS_INSERTQ, nullptr}, - {X86_INS_INSD, &Capstone2LlvmIrTranslatorX86_impl::translateIns}, - {X86_INS_INSW, &Capstone2LlvmIrTranslatorX86_impl::translateIns}, - {X86_INS_INT, nullptr}, - {X86_INS_INT1, nullptr}, - {X86_INS_INT3, nullptr}, - {X86_INS_INTO, nullptr}, - {X86_INS_INVD, nullptr}, - {X86_INS_INVEPT, nullptr}, - {X86_INS_INVLPG, nullptr}, - {X86_INS_INVLPGA, nullptr}, - {X86_INS_INVPCID, nullptr}, - {X86_INS_INVVPID, nullptr}, - {X86_INS_IRET, nullptr}, - {X86_INS_IRETD, nullptr}, - {X86_INS_IRETQ, nullptr}, - {X86_INS_FISTTP, &Capstone2LlvmIrTranslatorX86_impl::translateFist}, - {X86_INS_FIST, &Capstone2LlvmIrTranslatorX86_impl::translateFist}, - {X86_INS_FISTP, &Capstone2LlvmIrTranslatorX86_impl::translateFist}, - {X86_INS_UCOMISD, nullptr}, - {X86_INS_UCOMISS, nullptr}, - {X86_INS_VCOMISD, nullptr}, - {X86_INS_VCOMISS, nullptr}, - {X86_INS_VCVTSD2SS, nullptr}, - {X86_INS_VCVTSI2SD, nullptr}, - {X86_INS_VCVTSI2SS, nullptr}, - {X86_INS_VCVTSS2SD, nullptr}, - {X86_INS_VCVTTSD2SI, nullptr}, - {X86_INS_VCVTTSD2USI, nullptr}, - {X86_INS_VCVTTSS2SI, nullptr}, - {X86_INS_VCVTTSS2USI, nullptr}, - {X86_INS_VCVTUSI2SD, nullptr}, - {X86_INS_VCVTUSI2SS, nullptr}, - {X86_INS_VUCOMISD, nullptr}, - {X86_INS_VUCOMISS, nullptr}, - {X86_INS_JAE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JA, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JBE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JB, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JCXZ, &Capstone2LlvmIrTranslatorX86_impl::translateJecxz}, - {X86_INS_JECXZ, &Capstone2LlvmIrTranslatorX86_impl::translateJecxz}, - {X86_INS_JE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JGE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JG, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JLE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JL, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JMP, &Capstone2LlvmIrTranslatorX86_impl::translateJmp}, - {X86_INS_JNE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JNO, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JNP, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JNS, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JO, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JP, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JRCXZ, &Capstone2LlvmIrTranslatorX86_impl::translateJecxz}, - {X86_INS_JS, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_KANDB, nullptr}, - {X86_INS_KANDD, nullptr}, - {X86_INS_KANDNB, nullptr}, - {X86_INS_KANDND, nullptr}, - {X86_INS_KANDNQ, nullptr}, - {X86_INS_KANDNW, nullptr}, - {X86_INS_KANDQ, nullptr}, - {X86_INS_KANDW, nullptr}, - {X86_INS_KMOVB, nullptr}, - {X86_INS_KMOVD, nullptr}, - {X86_INS_KMOVQ, nullptr}, - {X86_INS_KMOVW, nullptr}, - {X86_INS_KNOTB, nullptr}, - {X86_INS_KNOTD, nullptr}, - {X86_INS_KNOTQ, nullptr}, - {X86_INS_KNOTW, nullptr}, - {X86_INS_KORB, nullptr}, - {X86_INS_KORD, nullptr}, - {X86_INS_KORQ, nullptr}, - {X86_INS_KORTESTB, nullptr}, - {X86_INS_KORTESTD, nullptr}, - {X86_INS_KORTESTQ, nullptr}, - {X86_INS_KORTESTW, nullptr}, - {X86_INS_KORW, nullptr}, - {X86_INS_KSHIFTLB, nullptr}, - {X86_INS_KSHIFTLD, nullptr}, - {X86_INS_KSHIFTLQ, nullptr}, - {X86_INS_KSHIFTLW, nullptr}, - {X86_INS_KSHIFTRB, nullptr}, - {X86_INS_KSHIFTRD, nullptr}, - {X86_INS_KSHIFTRQ, nullptr}, - {X86_INS_KSHIFTRW, nullptr}, - {X86_INS_KUNPCKBW, nullptr}, - {X86_INS_KXNORB, nullptr}, - {X86_INS_KXNORD, nullptr}, - {X86_INS_KXNORQ, nullptr}, - {X86_INS_KXNORW, nullptr}, - {X86_INS_KXORB, nullptr}, - {X86_INS_KXORD, nullptr}, - {X86_INS_KXORQ, nullptr}, - {X86_INS_KXORW, nullptr}, - {X86_INS_LAHF, &Capstone2LlvmIrTranslatorX86_impl::translateLahf}, - {X86_INS_LAR, nullptr}, - {X86_INS_LDDQU, nullptr}, - {X86_INS_LDMXCSR, nullptr}, - {X86_INS_LDS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, - {X86_INS_FLDZ, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FLD1, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FLD, &Capstone2LlvmIrTranslatorX86_impl::translateFld}, - {X86_INS_LEA, &Capstone2LlvmIrTranslatorX86_impl::translateLea}, - {X86_INS_LEAVE, &Capstone2LlvmIrTranslatorX86_impl::translateLeave}, - {X86_INS_LES, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, - {X86_INS_LFENCE, nullptr}, - {X86_INS_LFS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, - {X86_INS_LGDT, nullptr}, - {X86_INS_LGS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, - {X86_INS_LIDT, nullptr}, - {X86_INS_LLDT, nullptr}, - {X86_INS_LMSW, nullptr}, - {X86_INS_OR, &Capstone2LlvmIrTranslatorX86_impl::translateOr}, - {X86_INS_SUB, &Capstone2LlvmIrTranslatorX86_impl::translateSub}, - {X86_INS_XOR, &Capstone2LlvmIrTranslatorX86_impl::translateXor}, - {X86_INS_LODSB, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, - {X86_INS_LODSD, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, - {X86_INS_LODSQ, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, - {X86_INS_LODSW, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, - {X86_INS_LOOP, &Capstone2LlvmIrTranslatorX86_impl::translateLoop}, - {X86_INS_LOOPE, &Capstone2LlvmIrTranslatorX86_impl::translateLoop}, - {X86_INS_LOOPNE, &Capstone2LlvmIrTranslatorX86_impl::translateLoop}, - {X86_INS_RETF, &Capstone2LlvmIrTranslatorX86_impl::translateRet}, - {X86_INS_RETFQ, &Capstone2LlvmIrTranslatorX86_impl::translateRet}, - {X86_INS_LSL, nullptr}, - {X86_INS_LSS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, - {X86_INS_LTR, nullptr}, - {X86_INS_XADD, &Capstone2LlvmIrTranslatorX86_impl::translateAdd}, - {X86_INS_LZCNT, nullptr}, - {X86_INS_MASKMOVDQU, nullptr}, - {X86_INS_MAXPD, nullptr}, - {X86_INS_MAXPS, nullptr}, - {X86_INS_MAXSD, nullptr}, - {X86_INS_MAXSS, nullptr}, - {X86_INS_MFENCE, nullptr}, - {X86_INS_MINPD, nullptr}, - {X86_INS_MINPS, nullptr}, - {X86_INS_MINSD, nullptr}, - {X86_INS_MINSS, nullptr}, - {X86_INS_CVTPD2PI, nullptr}, - {X86_INS_CVTPI2PD, nullptr}, - {X86_INS_CVTPI2PS, nullptr}, - {X86_INS_CVTPS2PI, nullptr}, - {X86_INS_CVTTPD2PI, nullptr}, - {X86_INS_CVTTPS2PI, nullptr}, - {X86_INS_EMMS, nullptr}, - {X86_INS_MASKMOVQ, nullptr}, - {X86_INS_MOVD, nullptr}, - {X86_INS_MOVDQ2Q, nullptr}, - {X86_INS_MOVNTQ, nullptr}, - {X86_INS_MOVQ2DQ, nullptr}, - {X86_INS_MOVQ, nullptr}, - {X86_INS_PABSB, nullptr}, - {X86_INS_PABSD, nullptr}, - {X86_INS_PABSW, nullptr}, - {X86_INS_PACKSSDW, nullptr}, - {X86_INS_PACKSSWB, nullptr}, - {X86_INS_PACKUSWB, nullptr}, - {X86_INS_PADDB, nullptr}, - {X86_INS_PADDD, nullptr}, - {X86_INS_PADDQ, nullptr}, - {X86_INS_PADDSB, nullptr}, - {X86_INS_PADDSW, nullptr}, - {X86_INS_PADDUSB, nullptr}, - {X86_INS_PADDUSW, nullptr}, - {X86_INS_PADDW, nullptr}, - {X86_INS_PALIGNR, nullptr}, - {X86_INS_PANDN, nullptr}, - {X86_INS_PAND, nullptr}, - {X86_INS_PAVGB, nullptr}, - {X86_INS_PAVGW, nullptr}, - {X86_INS_PCMPEQB, nullptr}, - {X86_INS_PCMPEQD, nullptr}, - {X86_INS_PCMPEQW, nullptr}, - {X86_INS_PCMPGTB, nullptr}, - {X86_INS_PCMPGTD, nullptr}, - {X86_INS_PCMPGTW, nullptr}, - {X86_INS_PEXTRW, nullptr}, - {X86_INS_PHADDSW, nullptr}, - {X86_INS_PHADDW, nullptr}, - {X86_INS_PHADDD, nullptr}, - {X86_INS_PHSUBD, nullptr}, - {X86_INS_PHSUBSW, nullptr}, - {X86_INS_PHSUBW, nullptr}, - {X86_INS_PINSRW, nullptr}, - {X86_INS_PMADDUBSW, nullptr}, - {X86_INS_PMADDWD, nullptr}, - {X86_INS_PMAXSW, nullptr}, - {X86_INS_PMAXUB, nullptr}, - {X86_INS_PMINSW, nullptr}, - {X86_INS_PMINUB, nullptr}, - {X86_INS_PMOVMSKB, nullptr}, - {X86_INS_PMULHRSW, nullptr}, - {X86_INS_PMULHUW, nullptr}, - {X86_INS_PMULHW, nullptr}, - {X86_INS_PMULLW, nullptr}, - {X86_INS_PMULUDQ, nullptr}, - {X86_INS_POR, nullptr}, - {X86_INS_PSADBW, nullptr}, - {X86_INS_PSHUFB, nullptr}, - {X86_INS_PSHUFW, nullptr}, - {X86_INS_PSIGNB, nullptr}, - {X86_INS_PSIGND, nullptr}, - {X86_INS_PSIGNW, nullptr}, - {X86_INS_PSLLD, nullptr}, - {X86_INS_PSLLQ, nullptr}, - {X86_INS_PSLLW, nullptr}, - {X86_INS_PSRAD, nullptr}, - {X86_INS_PSRAW, nullptr}, - {X86_INS_PSRLD, nullptr}, - {X86_INS_PSRLQ, nullptr}, - {X86_INS_PSRLW, nullptr}, - {X86_INS_PSUBB, nullptr}, - {X86_INS_PSUBD, nullptr}, - {X86_INS_PSUBQ, nullptr}, - {X86_INS_PSUBSB, nullptr}, - {X86_INS_PSUBSW, nullptr}, - {X86_INS_PSUBUSB, nullptr}, - {X86_INS_PSUBUSW, nullptr}, - {X86_INS_PSUBW, nullptr}, - {X86_INS_PUNPCKHBW, nullptr}, - {X86_INS_PUNPCKHDQ, nullptr}, - {X86_INS_PUNPCKHWD, nullptr}, - {X86_INS_PUNPCKLBW, nullptr}, - {X86_INS_PUNPCKLDQ, nullptr}, - {X86_INS_PUNPCKLWD, nullptr}, - {X86_INS_PXOR, nullptr}, - {X86_INS_MONITOR, nullptr}, - {X86_INS_MONTMUL, nullptr}, - {X86_INS_MOV, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, - {X86_INS_MOVABS, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, - {X86_INS_MOVBE, nullptr}, - {X86_INS_MOVDDUP, nullptr}, - {X86_INS_MOVDQA, nullptr}, - {X86_INS_MOVDQU, nullptr}, - {X86_INS_MOVHLPS, nullptr}, - {X86_INS_MOVHPD, nullptr}, - {X86_INS_MOVHPS, nullptr}, - {X86_INS_MOVLHPS, nullptr}, - {X86_INS_MOVLPD, nullptr}, - {X86_INS_MOVLPS, nullptr}, - {X86_INS_MOVMSKPD, nullptr}, - {X86_INS_MOVMSKPS, nullptr}, - {X86_INS_MOVNTDQA, nullptr}, - {X86_INS_MOVNTDQ, nullptr}, - {X86_INS_MOVNTI, nullptr}, - {X86_INS_MOVNTPD, nullptr}, - {X86_INS_MOVNTPS, nullptr}, - {X86_INS_MOVNTSD, nullptr}, - {X86_INS_MOVNTSS, nullptr}, - {X86_INS_MOVSB, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, - {X86_INS_MOVSD, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, - {X86_INS_MOVSHDUP, nullptr}, - {X86_INS_MOVSLDUP, nullptr}, - {X86_INS_MOVSQ, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, - {X86_INS_MOVSS, nullptr}, - {X86_INS_MOVSW, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, - {X86_INS_MOVSX, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, - {X86_INS_MOVSXD, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, - {X86_INS_MOVUPD, nullptr}, - {X86_INS_MOVUPS, nullptr}, - {X86_INS_MOVZX, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, - {X86_INS_MPSADBW, nullptr}, - {X86_INS_MUL, &Capstone2LlvmIrTranslatorX86_impl::translateMul}, - {X86_INS_MULPD, nullptr}, - {X86_INS_MULPS, nullptr}, - {X86_INS_MULSD, nullptr}, - {X86_INS_MULSS, nullptr}, - {X86_INS_MULX, nullptr}, - {X86_INS_FMUL, &Capstone2LlvmIrTranslatorX86_impl::translateFmul}, - {X86_INS_FIMUL, &Capstone2LlvmIrTranslatorX86_impl::translateFmul}, - {X86_INS_FMULP, &Capstone2LlvmIrTranslatorX86_impl::translateFmul}, - {X86_INS_MWAIT, nullptr}, - {X86_INS_NEG, &Capstone2LlvmIrTranslatorX86_impl::translateNeg}, - {X86_INS_NOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_NOT, &Capstone2LlvmIrTranslatorX86_impl::translateNot}, - {X86_INS_OUT, nullptr}, - {X86_INS_OUTSB, &Capstone2LlvmIrTranslatorX86_impl::translateOuts}, - {X86_INS_OUTSD, &Capstone2LlvmIrTranslatorX86_impl::translateOuts}, - {X86_INS_OUTSW, &Capstone2LlvmIrTranslatorX86_impl::translateOuts}, - {X86_INS_PACKUSDW, nullptr}, - {X86_INS_PAUSE, nullptr}, - {X86_INS_PAVGUSB, nullptr}, - {X86_INS_PBLENDVB, nullptr}, - {X86_INS_PBLENDW, nullptr}, - {X86_INS_PCLMULQDQ, nullptr}, - {X86_INS_PCMPEQQ, nullptr}, - {X86_INS_PCMPESTRI, nullptr}, - {X86_INS_PCMPESTRM, nullptr}, - {X86_INS_PCMPGTQ, nullptr}, - {X86_INS_PCMPISTRI, nullptr}, - {X86_INS_PCMPISTRM, nullptr}, - {X86_INS_PDEP, nullptr}, - {X86_INS_PEXT, nullptr}, - {X86_INS_PEXTRB, nullptr}, - {X86_INS_PEXTRD, nullptr}, - {X86_INS_PEXTRQ, nullptr}, - {X86_INS_PF2ID, nullptr}, - {X86_INS_PF2IW, nullptr}, - {X86_INS_PFACC, nullptr}, - {X86_INS_PFADD, nullptr}, - {X86_INS_PFCMPEQ, nullptr}, - {X86_INS_PFCMPGE, nullptr}, - {X86_INS_PFCMPGT, nullptr}, - {X86_INS_PFMAX, nullptr}, - {X86_INS_PFMIN, nullptr}, - {X86_INS_PFMUL, nullptr}, - {X86_INS_PFNACC, nullptr}, - {X86_INS_PFPNACC, nullptr}, - {X86_INS_PFRCPIT1, nullptr}, - {X86_INS_PFRCPIT2, nullptr}, - {X86_INS_PFRCP, nullptr}, - {X86_INS_PFRSQIT1, nullptr}, - {X86_INS_PFRSQRT, nullptr}, - {X86_INS_PFSUBR, nullptr}, - {X86_INS_PFSUB, nullptr}, - {X86_INS_PHMINPOSUW, nullptr}, - {X86_INS_PI2FD, nullptr}, - {X86_INS_PI2FW, nullptr}, - {X86_INS_PINSRB, nullptr}, - {X86_INS_PINSRD, nullptr}, - {X86_INS_PINSRQ, nullptr}, - {X86_INS_PMAXSB, nullptr}, - {X86_INS_PMAXSD, nullptr}, - {X86_INS_PMAXUD, nullptr}, - {X86_INS_PMAXUW, nullptr}, - {X86_INS_PMINSB, nullptr}, - {X86_INS_PMINSD, nullptr}, - {X86_INS_PMINUD, nullptr}, - {X86_INS_PMINUW, nullptr}, - {X86_INS_PMOVSXBD, nullptr}, - {X86_INS_PMOVSXBQ, nullptr}, - {X86_INS_PMOVSXBW, nullptr}, - {X86_INS_PMOVSXDQ, nullptr}, - {X86_INS_PMOVSXWD, nullptr}, - {X86_INS_PMOVSXWQ, nullptr}, - {X86_INS_PMOVZXBD, nullptr}, - {X86_INS_PMOVZXBQ, nullptr}, - {X86_INS_PMOVZXBW, nullptr}, - {X86_INS_PMOVZXDQ, nullptr}, - {X86_INS_PMOVZXWD, nullptr}, - {X86_INS_PMOVZXWQ, nullptr}, - {X86_INS_PMULDQ, nullptr}, - {X86_INS_PMULHRW, nullptr}, - {X86_INS_PMULLD, nullptr}, - {X86_INS_POP, &Capstone2LlvmIrTranslatorX86_impl::translatePop}, - {X86_INS_POPAW, &Capstone2LlvmIrTranslatorX86_impl::translatePopa}, // X86_INS_POPAW == POPA - {X86_INS_POPAL, &Capstone2LlvmIrTranslatorX86_impl::translatePopa}, // X86_INS_POPAL == POPAD - {X86_INS_POPCNT, nullptr}, - {X86_INS_POPF, &Capstone2LlvmIrTranslatorX86_impl::translatePopEflags}, - {X86_INS_POPFD, &Capstone2LlvmIrTranslatorX86_impl::translatePopEflags}, - {X86_INS_POPFQ, &Capstone2LlvmIrTranslatorX86_impl::translatePopEflags}, - {X86_INS_PREFETCH, nullptr}, - {X86_INS_PREFETCHNTA, nullptr}, - {X86_INS_PREFETCHT0, nullptr}, - {X86_INS_PREFETCHT1, nullptr}, - {X86_INS_PREFETCHT2, nullptr}, - {X86_INS_PREFETCHW, nullptr}, - {X86_INS_PSHUFD, nullptr}, - {X86_INS_PSHUFHW, nullptr}, - {X86_INS_PSHUFLW, nullptr}, - {X86_INS_PSLLDQ, nullptr}, - {X86_INS_PSRLDQ, nullptr}, - {X86_INS_PSWAPD, nullptr}, - {X86_INS_PTEST, nullptr}, - {X86_INS_PUNPCKHQDQ, nullptr}, - {X86_INS_PUNPCKLQDQ, nullptr}, - {X86_INS_PUSH, &Capstone2LlvmIrTranslatorX86_impl::translatePush}, - {X86_INS_PUSHAW, &Capstone2LlvmIrTranslatorX86_impl::translatePusha}, // X86_INS_PUSHAW = PUSHA - {X86_INS_PUSHAL, &Capstone2LlvmIrTranslatorX86_impl::translatePusha}, // X86_INS_PUSHAL = PUSHAD - {X86_INS_PUSHF, &Capstone2LlvmIrTranslatorX86_impl::translatePushEflags}, - {X86_INS_PUSHFD, &Capstone2LlvmIrTranslatorX86_impl::translatePushEflags}, - {X86_INS_PUSHFQ, &Capstone2LlvmIrTranslatorX86_impl::translatePushEflags}, - {X86_INS_RCL, &Capstone2LlvmIrTranslatorX86_impl::translateRcl}, - {X86_INS_RCPPS, nullptr}, - {X86_INS_RCPSS, nullptr}, - {X86_INS_RCR, &Capstone2LlvmIrTranslatorX86_impl::translateRcr}, - {X86_INS_RDFSBASE, nullptr}, - {X86_INS_RDGSBASE, nullptr}, - {X86_INS_RDMSR, nullptr}, - {X86_INS_RDPMC, nullptr}, - {X86_INS_RDRAND, nullptr}, - {X86_INS_RDSEED, nullptr}, - {X86_INS_RDTSC, &Capstone2LlvmIrTranslatorX86_impl::translateRdtsc}, - {X86_INS_RDTSCP, &Capstone2LlvmIrTranslatorX86_impl::translateRdtscp}, - {X86_INS_ROL, &Capstone2LlvmIrTranslatorX86_impl::translateRol}, - {X86_INS_ROR, &Capstone2LlvmIrTranslatorX86_impl::translateRor}, - {X86_INS_RORX, nullptr}, - {X86_INS_ROUNDPD, nullptr}, - {X86_INS_ROUNDPS, nullptr}, - {X86_INS_ROUNDSD, nullptr}, - {X86_INS_ROUNDSS, nullptr}, - {X86_INS_RSM, nullptr}, - {X86_INS_RSQRTPS, nullptr}, - {X86_INS_RSQRTSS, nullptr}, - {X86_INS_SAHF, &Capstone2LlvmIrTranslatorX86_impl::translateSahf}, - {X86_INS_SAL, &Capstone2LlvmIrTranslatorX86_impl::translateShiftLeft}, - {X86_INS_SALC, &Capstone2LlvmIrTranslatorX86_impl::translateSalc}, - {X86_INS_SAR, &Capstone2LlvmIrTranslatorX86_impl::translateShiftRight}, - {X86_INS_SARX, nullptr}, - {X86_INS_SBB, &Capstone2LlvmIrTranslatorX86_impl::translateSbb}, - {X86_INS_SCASB, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, - {X86_INS_SCASD, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, - {X86_INS_SCASQ, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, - {X86_INS_SCASW, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, - {X86_INS_SETAE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETA, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETBE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETB, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETGE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETG, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETLE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETL, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETNE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETNO, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETNP, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETNS, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETO, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETP, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETS, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SFENCE, nullptr}, - {X86_INS_SGDT, nullptr}, - {X86_INS_SHA1MSG1, nullptr}, - {X86_INS_SHA1MSG2, nullptr}, - {X86_INS_SHA1NEXTE, nullptr}, - {X86_INS_SHA1RNDS4, nullptr}, - {X86_INS_SHA256MSG1, nullptr}, - {X86_INS_SHA256MSG2, nullptr}, - {X86_INS_SHA256RNDS2, nullptr}, - {X86_INS_SHL, &Capstone2LlvmIrTranslatorX86_impl::translateShiftLeft}, - {X86_INS_SHLD, &Capstone2LlvmIrTranslatorX86_impl::translateShld}, - {X86_INS_SHLX, nullptr}, - {X86_INS_SHR, &Capstone2LlvmIrTranslatorX86_impl::translateShiftRight}, - {X86_INS_SHRD, &Capstone2LlvmIrTranslatorX86_impl::translateShrd}, - {X86_INS_SHRX, nullptr}, - {X86_INS_SHUFPD, nullptr}, - {X86_INS_SHUFPS, nullptr}, - {X86_INS_SIDT, nullptr}, - {X86_INS_FSIN, &Capstone2LlvmIrTranslatorX86_impl::translateFsin}, - {X86_INS_SKINIT, nullptr}, - {X86_INS_SLDT, nullptr}, - {X86_INS_SMSW, nullptr}, - {X86_INS_SQRTPD, nullptr}, - {X86_INS_SQRTPS, nullptr}, - {X86_INS_SQRTSD, nullptr}, - {X86_INS_SQRTSS, nullptr}, - {X86_INS_FSQRT, &Capstone2LlvmIrTranslatorX86_impl::translateFsqrt}, - {X86_INS_STAC, nullptr}, - {X86_INS_STC, &Capstone2LlvmIrTranslatorX86_impl::translateStc}, - {X86_INS_STD, &Capstone2LlvmIrTranslatorX86_impl::translateStd}, - {X86_INS_STGI, nullptr}, - {X86_INS_STI, nullptr}, - {X86_INS_STMXCSR, nullptr}, - {X86_INS_STOSB, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, - {X86_INS_STOSD, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, - {X86_INS_STOSQ, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, - {X86_INS_STOSW, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, - {X86_INS_STR, nullptr}, - {X86_INS_FST, &Capstone2LlvmIrTranslatorX86_impl::translateFst}, - {X86_INS_FSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFst}, - {X86_INS_FSTPNCE, nullptr}, - {X86_INS_FXCH, &Capstone2LlvmIrTranslatorX86_impl::translateFxch}, - {X86_INS_SUBPD, nullptr}, - {X86_INS_SUBPS, nullptr}, - {X86_INS_FSUBR, &Capstone2LlvmIrTranslatorX86_impl::translateFsubr}, - {X86_INS_FISUBR, &Capstone2LlvmIrTranslatorX86_impl::translateFsubr}, - {X86_INS_FSUBRP, &Capstone2LlvmIrTranslatorX86_impl::translateFsubr}, - {X86_INS_SUBSD, nullptr}, - {X86_INS_SUBSS, nullptr}, - {X86_INS_FSUB, &Capstone2LlvmIrTranslatorX86_impl::translateFsub}, - {X86_INS_FISUB, &Capstone2LlvmIrTranslatorX86_impl::translateFsub}, - {X86_INS_FSUBP, &Capstone2LlvmIrTranslatorX86_impl::translateFsub}, - {X86_INS_SWAPGS, nullptr}, - {X86_INS_SYSCALL, nullptr}, - {X86_INS_SYSENTER, nullptr}, - {X86_INS_SYSEXIT, nullptr}, - {X86_INS_SYSRET, nullptr}, - {X86_INS_T1MSKC, nullptr}, - {X86_INS_TEST, &Capstone2LlvmIrTranslatorX86_impl::translateAnd}, - {X86_INS_UD2, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_FTST, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_TZCNT, nullptr}, - {X86_INS_TZMSK, nullptr}, - {X86_INS_FUCOMPI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FUCOMI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FUCOMPP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FUCOMP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FUCOM, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_UD1, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_UNPCKHPD, nullptr}, - {X86_INS_UNPCKHPS, nullptr}, - {X86_INS_UNPCKLPD, nullptr}, - {X86_INS_UNPCKLPS, nullptr}, - {X86_INS_VADDPD, nullptr}, - {X86_INS_VADDPS, nullptr}, - {X86_INS_VADDSD, nullptr}, - {X86_INS_VADDSS, nullptr}, - {X86_INS_VADDSUBPD, nullptr}, - {X86_INS_VADDSUBPS, nullptr}, - {X86_INS_VAESDECLAST, nullptr}, - {X86_INS_VAESDEC, nullptr}, - {X86_INS_VAESENCLAST, nullptr}, - {X86_INS_VAESENC, nullptr}, - {X86_INS_VAESIMC, nullptr}, - {X86_INS_VAESKEYGENASSIST, nullptr}, - {X86_INS_VALIGND, nullptr}, - {X86_INS_VALIGNQ, nullptr}, - {X86_INS_VANDNPD, nullptr}, - {X86_INS_VANDNPS, nullptr}, - {X86_INS_VANDPD, nullptr}, - {X86_INS_VANDPS, nullptr}, - {X86_INS_VBLENDMPD, nullptr}, - {X86_INS_VBLENDMPS, nullptr}, - {X86_INS_VBLENDPD, nullptr}, - {X86_INS_VBLENDPS, nullptr}, - {X86_INS_VBLENDVPD, nullptr}, - {X86_INS_VBLENDVPS, nullptr}, - {X86_INS_VBROADCASTF128, nullptr}, - {X86_INS_VBROADCASTI32X4, nullptr}, - {X86_INS_VBROADCASTI64X4, nullptr}, - {X86_INS_VBROADCASTSD, nullptr}, - {X86_INS_VBROADCASTSS, nullptr}, - {X86_INS_VCOMPRESSPD, nullptr}, - {X86_INS_VCOMPRESSPS, nullptr}, - {X86_INS_VCVTDQ2PD, nullptr}, - {X86_INS_VCVTDQ2PS, nullptr}, - {X86_INS_VCVTPD2DQ, nullptr}, - {X86_INS_VCVTPD2PS, nullptr}, - {X86_INS_VCVTPD2UDQ, nullptr}, - {X86_INS_VCVTPH2PS, nullptr}, - {X86_INS_VCVTPS2DQ, nullptr}, - {X86_INS_VCVTPS2PD, nullptr}, - {X86_INS_VCVTPS2PH, nullptr}, - {X86_INS_VCVTPS2UDQ, nullptr}, - {X86_INS_VCVTSD2SI, nullptr}, - {X86_INS_VCVTSD2USI, nullptr}, - {X86_INS_VCVTSS2SI, nullptr}, - {X86_INS_VCVTSS2USI, nullptr}, - {X86_INS_VCVTTPD2DQ, nullptr}, - {X86_INS_VCVTTPD2UDQ, nullptr}, - {X86_INS_VCVTTPS2DQ, nullptr}, - {X86_INS_VCVTTPS2UDQ, nullptr}, - {X86_INS_VCVTUDQ2PD, nullptr}, - {X86_INS_VCVTUDQ2PS, nullptr}, - {X86_INS_VDIVPD, nullptr}, - {X86_INS_VDIVPS, nullptr}, - {X86_INS_VDIVSD, nullptr}, - {X86_INS_VDIVSS, nullptr}, - {X86_INS_VDPPD, nullptr}, - {X86_INS_VDPPS, nullptr}, - {X86_INS_VERR, nullptr}, - {X86_INS_VERW, nullptr}, - {X86_INS_VEXP2PD, nullptr}, - {X86_INS_VEXP2PS, nullptr}, - {X86_INS_VEXPANDPD, nullptr}, - {X86_INS_VEXPANDPS, nullptr}, - {X86_INS_VEXTRACTF128, nullptr}, - {X86_INS_VEXTRACTF32X4, nullptr}, - {X86_INS_VEXTRACTF64X4, nullptr}, - {X86_INS_VEXTRACTI128, nullptr}, - {X86_INS_VEXTRACTI32X4, nullptr}, - {X86_INS_VEXTRACTI64X4, nullptr}, - {X86_INS_VEXTRACTPS, nullptr}, - {X86_INS_VFMADD132PD, nullptr}, - {X86_INS_VFMADD132PS, nullptr}, - {X86_INS_VFMADDPD, nullptr}, - {X86_INS_VFMADD213PD, nullptr}, - {X86_INS_VFMADD231PD, nullptr}, - {X86_INS_VFMADDPS, nullptr}, - {X86_INS_VFMADD213PS, nullptr}, - {X86_INS_VFMADD231PS, nullptr}, - {X86_INS_VFMADDSD, nullptr}, - {X86_INS_VFMADD213SD, nullptr}, - {X86_INS_VFMADD132SD, nullptr}, - {X86_INS_VFMADD231SD, nullptr}, - {X86_INS_VFMADDSS, nullptr}, - {X86_INS_VFMADD213SS, nullptr}, - {X86_INS_VFMADD132SS, nullptr}, - {X86_INS_VFMADD231SS, nullptr}, - {X86_INS_VFMADDSUB132PD, nullptr}, - {X86_INS_VFMADDSUB132PS, nullptr}, - {X86_INS_VFMADDSUBPD, nullptr}, - {X86_INS_VFMADDSUB213PD, nullptr}, - {X86_INS_VFMADDSUB231PD, nullptr}, - {X86_INS_VFMADDSUBPS, nullptr}, - {X86_INS_VFMADDSUB213PS, nullptr}, - {X86_INS_VFMADDSUB231PS, nullptr}, - {X86_INS_VFMSUB132PD, nullptr}, - {X86_INS_VFMSUB132PS, nullptr}, - {X86_INS_VFMSUBADD132PD, nullptr}, - {X86_INS_VFMSUBADD132PS, nullptr}, - {X86_INS_VFMSUBADDPD, nullptr}, - {X86_INS_VFMSUBADD213PD, nullptr}, - {X86_INS_VFMSUBADD231PD, nullptr}, - {X86_INS_VFMSUBADDPS, nullptr}, - {X86_INS_VFMSUBADD213PS, nullptr}, - {X86_INS_VFMSUBADD231PS, nullptr}, - {X86_INS_VFMSUBPD, nullptr}, - {X86_INS_VFMSUB213PD, nullptr}, - {X86_INS_VFMSUB231PD, nullptr}, - {X86_INS_VFMSUBPS, nullptr}, - {X86_INS_VFMSUB213PS, nullptr}, - {X86_INS_VFMSUB231PS, nullptr}, - {X86_INS_VFMSUBSD, nullptr}, - {X86_INS_VFMSUB213SD, nullptr}, - {X86_INS_VFMSUB132SD, nullptr}, - {X86_INS_VFMSUB231SD, nullptr}, - {X86_INS_VFMSUBSS, nullptr}, - {X86_INS_VFMSUB213SS, nullptr}, - {X86_INS_VFMSUB132SS, nullptr}, - {X86_INS_VFMSUB231SS, nullptr}, - {X86_INS_VFNMADD132PD, nullptr}, - {X86_INS_VFNMADD132PS, nullptr}, - {X86_INS_VFNMADDPD, nullptr}, - {X86_INS_VFNMADD213PD, nullptr}, - {X86_INS_VFNMADD231PD, nullptr}, - {X86_INS_VFNMADDPS, nullptr}, - {X86_INS_VFNMADD213PS, nullptr}, - {X86_INS_VFNMADD231PS, nullptr}, - {X86_INS_VFNMADDSD, nullptr}, - {X86_INS_VFNMADD213SD, nullptr}, - {X86_INS_VFNMADD132SD, nullptr}, - {X86_INS_VFNMADD231SD, nullptr}, - {X86_INS_VFNMADDSS, nullptr}, - {X86_INS_VFNMADD213SS, nullptr}, - {X86_INS_VFNMADD132SS, nullptr}, - {X86_INS_VFNMADD231SS, nullptr}, - {X86_INS_VFNMSUB132PD, nullptr}, - {X86_INS_VFNMSUB132PS, nullptr}, - {X86_INS_VFNMSUBPD, nullptr}, - {X86_INS_VFNMSUB213PD, nullptr}, - {X86_INS_VFNMSUB231PD, nullptr}, - {X86_INS_VFNMSUBPS, nullptr}, - {X86_INS_VFNMSUB213PS, nullptr}, - {X86_INS_VFNMSUB231PS, nullptr}, - {X86_INS_VFNMSUBSD, nullptr}, - {X86_INS_VFNMSUB213SD, nullptr}, - {X86_INS_VFNMSUB132SD, nullptr}, - {X86_INS_VFNMSUB231SD, nullptr}, - {X86_INS_VFNMSUBSS, nullptr}, - {X86_INS_VFNMSUB213SS, nullptr}, - {X86_INS_VFNMSUB132SS, nullptr}, - {X86_INS_VFNMSUB231SS, nullptr}, - {X86_INS_VFRCZPD, nullptr}, - {X86_INS_VFRCZPS, nullptr}, - {X86_INS_VFRCZSD, nullptr}, - {X86_INS_VFRCZSS, nullptr}, - {X86_INS_VORPD, nullptr}, - {X86_INS_VORPS, nullptr}, - {X86_INS_VXORPD, nullptr}, - {X86_INS_VXORPS, nullptr}, - {X86_INS_VGATHERDPD, nullptr}, - {X86_INS_VGATHERDPS, nullptr}, - {X86_INS_VGATHERPF0DPD, nullptr}, - {X86_INS_VGATHERPF0DPS, nullptr}, - {X86_INS_VGATHERPF0QPD, nullptr}, - {X86_INS_VGATHERPF0QPS, nullptr}, - {X86_INS_VGATHERPF1DPD, nullptr}, - {X86_INS_VGATHERPF1DPS, nullptr}, - {X86_INS_VGATHERPF1QPD, nullptr}, - {X86_INS_VGATHERPF1QPS, nullptr}, - {X86_INS_VGATHERQPD, nullptr}, - {X86_INS_VGATHERQPS, nullptr}, - {X86_INS_VHADDPD, nullptr}, - {X86_INS_VHADDPS, nullptr}, - {X86_INS_VHSUBPD, nullptr}, - {X86_INS_VHSUBPS, nullptr}, - {X86_INS_VINSERTF128, nullptr}, - {X86_INS_VINSERTF32X4, nullptr}, - {X86_INS_VINSERTF32X8, nullptr}, - {X86_INS_VINSERTF64X2, nullptr}, - {X86_INS_VINSERTF64X4, nullptr}, - {X86_INS_VINSERTI128, nullptr}, - {X86_INS_VINSERTI32X4, nullptr}, - {X86_INS_VINSERTI32X8, nullptr}, - {X86_INS_VINSERTI64X2, nullptr}, - {X86_INS_VINSERTI64X4, nullptr}, - {X86_INS_VINSERTPS, nullptr}, - {X86_INS_VLDDQU, nullptr}, - {X86_INS_VLDMXCSR, nullptr}, - {X86_INS_VMASKMOVDQU, nullptr}, - {X86_INS_VMASKMOVPD, nullptr}, - {X86_INS_VMASKMOVPS, nullptr}, - {X86_INS_VMAXPD, nullptr}, - {X86_INS_VMAXPS, nullptr}, - {X86_INS_VMAXSD, nullptr}, - {X86_INS_VMAXSS, nullptr}, - {X86_INS_VMCALL, nullptr}, - {X86_INS_VMCLEAR, nullptr}, - {X86_INS_VMFUNC, nullptr}, - {X86_INS_VMINPD, nullptr}, - {X86_INS_VMINPS, nullptr}, - {X86_INS_VMINSD, nullptr}, - {X86_INS_VMINSS, nullptr}, - {X86_INS_VMLAUNCH, nullptr}, - {X86_INS_VMLOAD, nullptr}, - {X86_INS_VMMCALL, nullptr}, - {X86_INS_VMOVQ, nullptr}, - {X86_INS_VMOVDDUP, nullptr}, - {X86_INS_VMOVD, nullptr}, - {X86_INS_VMOVDQA32, nullptr}, - {X86_INS_VMOVDQA64, nullptr}, - {X86_INS_VMOVDQA, nullptr}, - {X86_INS_VMOVDQU16, nullptr}, - {X86_INS_VMOVDQU32, nullptr}, - {X86_INS_VMOVDQU64, nullptr}, - {X86_INS_VMOVDQU8, nullptr}, - {X86_INS_VMOVDQU, nullptr}, - {X86_INS_VMOVHLPS, nullptr}, - {X86_INS_VMOVHPD, nullptr}, - {X86_INS_VMOVHPS, nullptr}, - {X86_INS_VMOVLHPS, nullptr}, - {X86_INS_VMOVLPD, nullptr}, - {X86_INS_VMOVLPS, nullptr}, - {X86_INS_VMOVMSKPD, nullptr}, - {X86_INS_VMOVMSKPS, nullptr}, - {X86_INS_VMOVNTDQA, nullptr}, - {X86_INS_VMOVNTDQ, nullptr}, - {X86_INS_VMOVNTPD, nullptr}, - {X86_INS_VMOVNTPS, nullptr}, - {X86_INS_VMOVSD, nullptr}, - {X86_INS_VMOVSHDUP, nullptr}, - {X86_INS_VMOVSLDUP, nullptr}, - {X86_INS_VMOVSS, nullptr}, - {X86_INS_VMOVUPD, nullptr}, - {X86_INS_VMOVUPS, nullptr}, - {X86_INS_VMPSADBW, nullptr}, - {X86_INS_VMPTRLD, nullptr}, - {X86_INS_VMPTRST, nullptr}, - {X86_INS_VMREAD, nullptr}, - {X86_INS_VMRESUME, nullptr}, - {X86_INS_VMRUN, nullptr}, - {X86_INS_VMSAVE, nullptr}, - {X86_INS_VMULPD, nullptr}, - {X86_INS_VMULPS, nullptr}, - {X86_INS_VMULSD, nullptr}, - {X86_INS_VMULSS, nullptr}, - {X86_INS_VMWRITE, nullptr}, - {X86_INS_VMXOFF, nullptr}, - {X86_INS_VMXON, nullptr}, - {X86_INS_VPABSB, nullptr}, - {X86_INS_VPABSD, nullptr}, - {X86_INS_VPABSQ, nullptr}, - {X86_INS_VPABSW, nullptr}, - {X86_INS_VPACKSSDW, nullptr}, - {X86_INS_VPACKSSWB, nullptr}, - {X86_INS_VPACKUSDW, nullptr}, - {X86_INS_VPACKUSWB, nullptr}, - {X86_INS_VPADDB, nullptr}, - {X86_INS_VPADDD, nullptr}, - {X86_INS_VPADDQ, nullptr}, - {X86_INS_VPADDSB, nullptr}, - {X86_INS_VPADDSW, nullptr}, - {X86_INS_VPADDUSB, nullptr}, - {X86_INS_VPADDUSW, nullptr}, - {X86_INS_VPADDW, nullptr}, - {X86_INS_VPALIGNR, nullptr}, - {X86_INS_VPANDD, nullptr}, - {X86_INS_VPANDND, nullptr}, - {X86_INS_VPANDNQ, nullptr}, - {X86_INS_VPANDN, nullptr}, - {X86_INS_VPANDQ, nullptr}, - {X86_INS_VPAND, nullptr}, - {X86_INS_VPAVGB, nullptr}, - {X86_INS_VPAVGW, nullptr}, - {X86_INS_VPBLENDD, nullptr}, - {X86_INS_VPBLENDMB, nullptr}, - {X86_INS_VPBLENDMD, nullptr}, - {X86_INS_VPBLENDMQ, nullptr}, - {X86_INS_VPBLENDMW, nullptr}, - {X86_INS_VPBLENDVB, nullptr}, - {X86_INS_VPBLENDW, nullptr}, - {X86_INS_VPBROADCASTB, nullptr}, - {X86_INS_VPBROADCASTD, nullptr}, - {X86_INS_VPBROADCASTMB2Q, nullptr}, - {X86_INS_VPBROADCASTMW2D, nullptr}, - {X86_INS_VPBROADCASTQ, nullptr}, - {X86_INS_VPBROADCASTW, nullptr}, - {X86_INS_VPCLMULQDQ, nullptr}, - {X86_INS_VPCMOV, nullptr}, - {X86_INS_VPCMPB, nullptr}, - {X86_INS_VPCMPD, nullptr}, - {X86_INS_VPCMPEQB, nullptr}, - {X86_INS_VPCMPEQD, nullptr}, - {X86_INS_VPCMPEQQ, nullptr}, - {X86_INS_VPCMPEQW, nullptr}, - {X86_INS_VPCMPESTRI, nullptr}, - {X86_INS_VPCMPESTRM, nullptr}, - {X86_INS_VPCMPGTB, nullptr}, - {X86_INS_VPCMPGTD, nullptr}, - {X86_INS_VPCMPGTQ, nullptr}, - {X86_INS_VPCMPGTW, nullptr}, - {X86_INS_VPCMPISTRI, nullptr}, - {X86_INS_VPCMPISTRM, nullptr}, - {X86_INS_VPCMPQ, nullptr}, - {X86_INS_VPCMPUB, nullptr}, - {X86_INS_VPCMPUD, nullptr}, - {X86_INS_VPCMPUQ, nullptr}, - {X86_INS_VPCMPUW, nullptr}, - {X86_INS_VPCMPW, nullptr}, - {X86_INS_VPCOMB, nullptr}, - {X86_INS_VPCOMD, nullptr}, - {X86_INS_VPCOMPRESSD, nullptr}, - {X86_INS_VPCOMPRESSQ, nullptr}, - {X86_INS_VPCOMQ, nullptr}, - {X86_INS_VPCOMUB, nullptr}, - {X86_INS_VPCOMUD, nullptr}, - {X86_INS_VPCOMUQ, nullptr}, - {X86_INS_VPCOMUW, nullptr}, - {X86_INS_VPCOMW, nullptr}, - {X86_INS_VPCONFLICTD, nullptr}, - {X86_INS_VPCONFLICTQ, nullptr}, - {X86_INS_VPERM2F128, nullptr}, - {X86_INS_VPERM2I128, nullptr}, - {X86_INS_VPERMD, nullptr}, - {X86_INS_VPERMI2D, nullptr}, - {X86_INS_VPERMI2PD, nullptr}, - {X86_INS_VPERMI2PS, nullptr}, - {X86_INS_VPERMI2Q, nullptr}, - {X86_INS_VPERMIL2PD, nullptr}, - {X86_INS_VPERMIL2PS, nullptr}, - {X86_INS_VPERMILPD, nullptr}, - {X86_INS_VPERMILPS, nullptr}, - {X86_INS_VPERMPD, nullptr}, - {X86_INS_VPERMPS, nullptr}, - {X86_INS_VPERMQ, nullptr}, - {X86_INS_VPERMT2D, nullptr}, - {X86_INS_VPERMT2PD, nullptr}, - {X86_INS_VPERMT2PS, nullptr}, - {X86_INS_VPERMT2Q, nullptr}, - {X86_INS_VPEXPANDD, nullptr}, - {X86_INS_VPEXPANDQ, nullptr}, - {X86_INS_VPEXTRB, nullptr}, - {X86_INS_VPEXTRD, nullptr}, - {X86_INS_VPEXTRQ, nullptr}, - {X86_INS_VPEXTRW, nullptr}, - {X86_INS_VPGATHERDD, nullptr}, - {X86_INS_VPGATHERDQ, nullptr}, - {X86_INS_VPGATHERQD, nullptr}, - {X86_INS_VPGATHERQQ, nullptr}, - {X86_INS_VPHADDBD, nullptr}, - {X86_INS_VPHADDBQ, nullptr}, - {X86_INS_VPHADDBW, nullptr}, - {X86_INS_VPHADDDQ, nullptr}, - {X86_INS_VPHADDD, nullptr}, - {X86_INS_VPHADDSW, nullptr}, - {X86_INS_VPHADDUBD, nullptr}, - {X86_INS_VPHADDUBQ, nullptr}, - {X86_INS_VPHADDUBW, nullptr}, - {X86_INS_VPHADDUDQ, nullptr}, - {X86_INS_VPHADDUWD, nullptr}, - {X86_INS_VPHADDUWQ, nullptr}, - {X86_INS_VPHADDWD, nullptr}, - {X86_INS_VPHADDWQ, nullptr}, - {X86_INS_VPHADDW, nullptr}, - {X86_INS_VPHMINPOSUW, nullptr}, - {X86_INS_VPHSUBBW, nullptr}, - {X86_INS_VPHSUBDQ, nullptr}, - {X86_INS_VPHSUBD, nullptr}, - {X86_INS_VPHSUBSW, nullptr}, - {X86_INS_VPHSUBWD, nullptr}, - {X86_INS_VPHSUBW, nullptr}, - {X86_INS_VPINSRB, nullptr}, - {X86_INS_VPINSRD, nullptr}, - {X86_INS_VPINSRQ, nullptr}, - {X86_INS_VPINSRW, nullptr}, - {X86_INS_VPLZCNTD, nullptr}, - {X86_INS_VPLZCNTQ, nullptr}, - {X86_INS_VPMACSDD, nullptr}, - {X86_INS_VPMACSDQH, nullptr}, - {X86_INS_VPMACSDQL, nullptr}, - {X86_INS_VPMACSSDD, nullptr}, - {X86_INS_VPMACSSDQH, nullptr}, - {X86_INS_VPMACSSDQL, nullptr}, - {X86_INS_VPMACSSWD, nullptr}, - {X86_INS_VPMACSSWW, nullptr}, - {X86_INS_VPMACSWD, nullptr}, - {X86_INS_VPMACSWW, nullptr}, - {X86_INS_VPMADCSSWD, nullptr}, - {X86_INS_VPMADCSWD, nullptr}, - {X86_INS_VPMADDUBSW, nullptr}, - {X86_INS_VPMADDWD, nullptr}, - {X86_INS_VPMASKMOVD, nullptr}, - {X86_INS_VPMASKMOVQ, nullptr}, - {X86_INS_VPMAXSB, nullptr}, - {X86_INS_VPMAXSD, nullptr}, - {X86_INS_VPMAXSQ, nullptr}, - {X86_INS_VPMAXSW, nullptr}, - {X86_INS_VPMAXUB, nullptr}, - {X86_INS_VPMAXUD, nullptr}, - {X86_INS_VPMAXUQ, nullptr}, - {X86_INS_VPMAXUW, nullptr}, - {X86_INS_VPMINSB, nullptr}, - {X86_INS_VPMINSD, nullptr}, - {X86_INS_VPMINSQ, nullptr}, - {X86_INS_VPMINSW, nullptr}, - {X86_INS_VPMINUB, nullptr}, - {X86_INS_VPMINUD, nullptr}, - {X86_INS_VPMINUQ, nullptr}, - {X86_INS_VPMINUW, nullptr}, - {X86_INS_VPMOVDB, nullptr}, - {X86_INS_VPMOVDW, nullptr}, - {X86_INS_VPMOVM2B, nullptr}, - {X86_INS_VPMOVM2D, nullptr}, - {X86_INS_VPMOVM2Q, nullptr}, - {X86_INS_VPMOVM2W, nullptr}, - {X86_INS_VPMOVMSKB, nullptr}, - {X86_INS_VPMOVQB, nullptr}, - {X86_INS_VPMOVQD, nullptr}, - {X86_INS_VPMOVQW, nullptr}, - {X86_INS_VPMOVSDB, nullptr}, - {X86_INS_VPMOVSDW, nullptr}, - {X86_INS_VPMOVSQB, nullptr}, - {X86_INS_VPMOVSQD, nullptr}, - {X86_INS_VPMOVSQW, nullptr}, - {X86_INS_VPMOVSXBD, nullptr}, - {X86_INS_VPMOVSXBQ, nullptr}, - {X86_INS_VPMOVSXBW, nullptr}, - {X86_INS_VPMOVSXDQ, nullptr}, - {X86_INS_VPMOVSXWD, nullptr}, - {X86_INS_VPMOVSXWQ, nullptr}, - {X86_INS_VPMOVUSDB, nullptr}, - {X86_INS_VPMOVUSDW, nullptr}, - {X86_INS_VPMOVUSQB, nullptr}, - {X86_INS_VPMOVUSQD, nullptr}, - {X86_INS_VPMOVUSQW, nullptr}, - {X86_INS_VPMOVZXBD, nullptr}, - {X86_INS_VPMOVZXBQ, nullptr}, - {X86_INS_VPMOVZXBW, nullptr}, - {X86_INS_VPMOVZXDQ, nullptr}, - {X86_INS_VPMOVZXWD, nullptr}, - {X86_INS_VPMOVZXWQ, nullptr}, - {X86_INS_VPMULDQ, nullptr}, - {X86_INS_VPMULHRSW, nullptr}, - {X86_INS_VPMULHUW, nullptr}, - {X86_INS_VPMULHW, nullptr}, - {X86_INS_VPMULLD, nullptr}, - {X86_INS_VPMULLQ, nullptr}, - {X86_INS_VPMULLW, nullptr}, - {X86_INS_VPMULUDQ, nullptr}, - {X86_INS_VPORD, nullptr}, - {X86_INS_VPORQ, nullptr}, - {X86_INS_VPOR, nullptr}, - {X86_INS_VPPERM, nullptr}, - {X86_INS_VPROTB, nullptr}, - {X86_INS_VPROTD, nullptr}, - {X86_INS_VPROTQ, nullptr}, - {X86_INS_VPROTW, nullptr}, - {X86_INS_VPSADBW, nullptr}, - {X86_INS_VPSCATTERDD, nullptr}, - {X86_INS_VPSCATTERDQ, nullptr}, - {X86_INS_VPSCATTERQD, nullptr}, - {X86_INS_VPSCATTERQQ, nullptr}, - {X86_INS_VPSHAB, nullptr}, - {X86_INS_VPSHAD, nullptr}, - {X86_INS_VPSHAQ, nullptr}, - {X86_INS_VPSHAW, nullptr}, - {X86_INS_VPSHLB, nullptr}, - {X86_INS_VPSHLD, nullptr}, - {X86_INS_VPSHLQ, nullptr}, - {X86_INS_VPSHLW, nullptr}, - {X86_INS_VPSHUFB, nullptr}, - {X86_INS_VPSHUFD, nullptr}, - {X86_INS_VPSHUFHW, nullptr}, - {X86_INS_VPSHUFLW, nullptr}, - {X86_INS_VPSIGNB, nullptr}, - {X86_INS_VPSIGND, nullptr}, - {X86_INS_VPSIGNW, nullptr}, - {X86_INS_VPSLLDQ, nullptr}, - {X86_INS_VPSLLD, nullptr}, - {X86_INS_VPSLLQ, nullptr}, - {X86_INS_VPSLLVD, nullptr}, - {X86_INS_VPSLLVQ, nullptr}, - {X86_INS_VPSLLW, nullptr}, - {X86_INS_VPSRAD, nullptr}, - {X86_INS_VPSRAQ, nullptr}, - {X86_INS_VPSRAVD, nullptr}, - {X86_INS_VPSRAVQ, nullptr}, - {X86_INS_VPSRAW, nullptr}, - {X86_INS_VPSRLDQ, nullptr}, - {X86_INS_VPSRLD, nullptr}, - {X86_INS_VPSRLQ, nullptr}, - {X86_INS_VPSRLVD, nullptr}, - {X86_INS_VPSRLVQ, nullptr}, - {X86_INS_VPSRLW, nullptr}, - {X86_INS_VPSUBB, nullptr}, - {X86_INS_VPSUBD, nullptr}, - {X86_INS_VPSUBQ, nullptr}, - {X86_INS_VPSUBSB, nullptr}, - {X86_INS_VPSUBSW, nullptr}, - {X86_INS_VPSUBUSB, nullptr}, - {X86_INS_VPSUBUSW, nullptr}, - {X86_INS_VPSUBW, nullptr}, - {X86_INS_VPTESTMD, nullptr}, - {X86_INS_VPTESTMQ, nullptr}, - {X86_INS_VPTESTNMD, nullptr}, - {X86_INS_VPTESTNMQ, nullptr}, - {X86_INS_VPTEST, nullptr}, - {X86_INS_VPUNPCKHBW, nullptr}, - {X86_INS_VPUNPCKHDQ, nullptr}, - {X86_INS_VPUNPCKHQDQ, nullptr}, - {X86_INS_VPUNPCKHWD, nullptr}, - {X86_INS_VPUNPCKLBW, nullptr}, - {X86_INS_VPUNPCKLDQ, nullptr}, - {X86_INS_VPUNPCKLQDQ, nullptr}, - {X86_INS_VPUNPCKLWD, nullptr}, - {X86_INS_VPXORD, nullptr}, - {X86_INS_VPXORQ, nullptr}, - {X86_INS_VPXOR, nullptr}, - {X86_INS_VRCP14PD, nullptr}, - {X86_INS_VRCP14PS, nullptr}, - {X86_INS_VRCP14SD, nullptr}, - {X86_INS_VRCP14SS, nullptr}, - {X86_INS_VRCP28PD, nullptr}, - {X86_INS_VRCP28PS, nullptr}, - {X86_INS_VRCP28SD, nullptr}, - {X86_INS_VRCP28SS, nullptr}, - {X86_INS_VRCPPS, nullptr}, - {X86_INS_VRCPSS, nullptr}, - {X86_INS_VRNDSCALEPD, nullptr}, - {X86_INS_VRNDSCALEPS, nullptr}, - {X86_INS_VRNDSCALESD, nullptr}, - {X86_INS_VRNDSCALESS, nullptr}, - {X86_INS_VROUNDPD, nullptr}, - {X86_INS_VROUNDPS, nullptr}, - {X86_INS_VROUNDSD, nullptr}, - {X86_INS_VROUNDSS, nullptr}, - {X86_INS_VRSQRT14PD, nullptr}, - {X86_INS_VRSQRT14PS, nullptr}, - {X86_INS_VRSQRT14SD, nullptr}, - {X86_INS_VRSQRT14SS, nullptr}, - {X86_INS_VRSQRT28PD, nullptr}, - {X86_INS_VRSQRT28PS, nullptr}, - {X86_INS_VRSQRT28SD, nullptr}, - {X86_INS_VRSQRT28SS, nullptr}, - {X86_INS_VRSQRTPS, nullptr}, - {X86_INS_VRSQRTSS, nullptr}, - {X86_INS_VSCATTERDPD, nullptr}, - {X86_INS_VSCATTERDPS, nullptr}, - {X86_INS_VSCATTERPF0DPD, nullptr}, - {X86_INS_VSCATTERPF0DPS, nullptr}, - {X86_INS_VSCATTERPF0QPD, nullptr}, - {X86_INS_VSCATTERPF0QPS, nullptr}, - {X86_INS_VSCATTERPF1DPD, nullptr}, - {X86_INS_VSCATTERPF1DPS, nullptr}, - {X86_INS_VSCATTERPF1QPD, nullptr}, - {X86_INS_VSCATTERPF1QPS, nullptr}, - {X86_INS_VSCATTERQPD, nullptr}, - {X86_INS_VSCATTERQPS, nullptr}, - {X86_INS_VSHUFPD, nullptr}, - {X86_INS_VSHUFPS, nullptr}, - {X86_INS_VSQRTPD, nullptr}, - {X86_INS_VSQRTPS, nullptr}, - {X86_INS_VSQRTSD, nullptr}, - {X86_INS_VSQRTSS, nullptr}, - {X86_INS_VSTMXCSR, nullptr}, - {X86_INS_VSUBPD, nullptr}, - {X86_INS_VSUBPS, nullptr}, - {X86_INS_VSUBSD, nullptr}, - {X86_INS_VSUBSS, nullptr}, - {X86_INS_VTESTPD, nullptr}, - {X86_INS_VTESTPS, nullptr}, - {X86_INS_VUNPCKHPD, nullptr}, - {X86_INS_VUNPCKHPS, nullptr}, - {X86_INS_VUNPCKLPD, nullptr}, - {X86_INS_VUNPCKLPS, nullptr}, - {X86_INS_VZEROALL, nullptr}, - {X86_INS_VZEROUPPER, nullptr}, - {X86_INS_WAIT, nullptr}, - {X86_INS_WBINVD, nullptr}, - {X86_INS_WRFSBASE, nullptr}, - {X86_INS_WRGSBASE, nullptr}, - {X86_INS_WRMSR, nullptr}, - {X86_INS_XABORT, nullptr}, - {X86_INS_XACQUIRE, nullptr}, - {X86_INS_XBEGIN, nullptr}, - {X86_INS_XCHG, &Capstone2LlvmIrTranslatorX86_impl::translateXchg}, - {X86_INS_XCRYPTCBC, nullptr}, - {X86_INS_XCRYPTCFB, nullptr}, - {X86_INS_XCRYPTCTR, nullptr}, - {X86_INS_XCRYPTECB, nullptr}, - {X86_INS_XCRYPTOFB, nullptr}, - {X86_INS_XEND, nullptr}, - {X86_INS_XGETBV, nullptr}, - {X86_INS_XLATB, &Capstone2LlvmIrTranslatorX86_impl::translateXlatb}, - {X86_INS_XRELEASE, nullptr}, - {X86_INS_XRSTOR, nullptr}, - {X86_INS_XRSTOR64, nullptr}, - {X86_INS_XRSTORS, nullptr}, - {X86_INS_XRSTORS64, nullptr}, - {X86_INS_XSAVE, nullptr}, - {X86_INS_XSAVE64, nullptr}, - {X86_INS_XSAVEC, nullptr}, - {X86_INS_XSAVEC64, nullptr}, - {X86_INS_XSAVEOPT, nullptr}, - {X86_INS_XSAVEOPT64, nullptr}, - {X86_INS_XSAVES, nullptr}, - {X86_INS_XSAVES64, nullptr}, - {X86_INS_XSETBV, nullptr}, - {X86_INS_XSHA1, nullptr}, - {X86_INS_XSHA256, nullptr}, - {X86_INS_XSTORE, nullptr}, - {X86_INS_XTEST, nullptr}, - {X86_INS_FDISI8087_NOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_FENI8087_NOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - - // pseudo instructions - {X86_INS_CMPSS, nullptr}, - {X86_INS_CMPSD, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, - {X86_INS_CMPPS, nullptr}, - {X86_INS_CMPPD, nullptr}, - {X86_INS_VCMPSS, nullptr}, - {X86_INS_VCMPSD, nullptr}, - {X86_INS_VCMPPS, nullptr}, - {X86_INS_VCMPPD, nullptr}, - {X86_INS_ENDBR32, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_ENDBR64, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - - {X86_INS_ENDING, nullptr}, // mark the end of the list of insn -}; - -} // namespace capstone2llvmir -} // namespace retdec +/** + * @file src/capstone2llvmir/x86/x86_init.cpp + * @brief Initializations for X86 implementation of @c Capstone2LlvmIrTranslator. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#include "capstone2llvmir/x86/x86_impl.h" + +namespace retdec { +namespace capstone2llvmir { + +// +//============================================================================== +// Pure virtual methods from Capstone2LlvmIrTranslator_impl +//============================================================================== +// + +void Capstone2LlvmIrTranslatorX86_impl::initializeArchSpecific() +{ + initializeRegistersParentMap(); +} + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegNameMap() +{ + std::map r2n = + { + // x86_reg_rflags + // + {X86_REG_CF, "cf"}, + {X86_REG_PF, "pf"}, + {X86_REG_AF, "az"}, + {X86_REG_ZF, "zf"}, + {X86_REG_SF, "sf"}, + {X86_REG_TF, "tf"}, + {X86_REG_IF, "if"}, + {X86_REG_DF, "df"}, + {X86_REG_OF, "of"}, + {X86_REG_IOPL, "iopl"}, + {X86_REG_NT, "nt"}, + {X86_REG_RF, "rf"}, + {X86_REG_VM, "vm"}, + {X86_REG_AC, "ac"}, + {X86_REG_VIF, "vif"}, + {X86_REG_VIP, "vip"}, + {X86_REG_ID, "id"}, + + // x87_reg_status + // + {X87_REG_IE, "fpu_stat_IE"}, + {X87_REG_DE, "fpu_stat_DE"}, + {X87_REG_ZE, "fpu_stat_ZE"}, + {X87_REG_OE, "fpu_stat_OE"}, + {X87_REG_UE, "fpu_stat_UE"}, + {X87_REG_PE, "fpu_stat_PE"}, + {X87_REG_SF, "fpu_stat_SF"}, + {X87_REG_ES, "fpu_stat_ES"}, + {X87_REG_C0, "fpu_stat_C0"}, + {X87_REG_C1, "fpu_stat_C1"}, + {X87_REG_C2, "fpu_stat_C2"}, + {X87_REG_C3, "fpu_stat_C3"}, + {X87_REG_TOP, "fpu_stat_TOP"}, + {X87_REG_B, "fpu_stat_B"}, + + // x87_reg_control + // + {X87_REG_IM, "fpu_control_IM"}, + {X87_REG_DM, "fpu_control_DM"}, + {X87_REG_ZM, "fpu_control_ZM"}, + {X87_REG_OM, "fpu_control_OM"}, + {X87_REG_UM, "fpu_control_UM"}, + {X87_REG_PM, "fpu_control_PM"}, + {X87_REG_PC, "fpu_control_PC"}, + {X87_REG_RC, "fpu_control_RC"}, + {X87_REG_X, "fpu_control_X"}, + + // FPU data registers + // They are named as ST(X) in Capstone, which is not good for us. + // + {X86_REG_ST0, "st0"}, + {X86_REG_ST1, "st1"}, + {X86_REG_ST2, "st2"}, + {X86_REG_ST3, "st3"}, + {X86_REG_ST4, "st4"}, + {X86_REG_ST5, "st5"}, + {X86_REG_ST6, "st6"}, + {X86_REG_ST7, "st7"}, + }; + + _reg2name = std::move(r2n); +} + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegTypeMap() +{ + auto* i1 = llvm::IntegerType::getInt1Ty(_module->getContext()); + auto* i2 = llvm::IntegerType::getIntNTy(_module->getContext(), 2); + auto* i3 = llvm::IntegerType::getIntNTy(_module->getContext(), 3); + auto* i8 = llvm::IntegerType::getInt8Ty(_module->getContext()); + auto* i16 = llvm::IntegerType::getInt16Ty(_module->getContext()); + auto* i32 = llvm::IntegerType::getInt32Ty(_module->getContext()); + auto* i64 = llvm::IntegerType::getInt64Ty(_module->getContext()); + auto* i128 = llvm::IntegerType::getInt128Ty(_module->getContext()); + auto* i256 = llvm::IntegerType::getIntNTy(_module->getContext(), 256); + auto* i512 = llvm::IntegerType::getIntNTy(_module->getContext(), 512); + auto* fp64 = llvm::IntegerType::getDoubleTy(_module->getContext()); + auto* fp80 = llvm::IntegerType::getX86_FP80Ty(_module->getContext()); + + auto* defTy = _origBasicMode == CS_MODE_64 ? i64 : i32; + + std::map r2t = + { + // x86_reg + // + {X86_REG_AH, i8}, + {X86_REG_AL, i8}, + {X86_REG_CH, i8}, + {X86_REG_CL, i8}, + {X86_REG_DH, i8}, + {X86_REG_DL, i8}, + {X86_REG_BH, i8}, + {X86_REG_BL, i8}, + {X86_REG_SPL, i8}, + {X86_REG_BPL, i8}, + {X86_REG_DIL, i8}, + {X86_REG_SIL, i8}, + {X86_REG_R8B, i8}, + {X86_REG_R9B, i8}, + {X86_REG_R10B, i8}, + {X86_REG_R11B, i8}, + {X86_REG_R12B, i8}, + {X86_REG_R13B, i8}, + {X86_REG_R14B, i8}, + {X86_REG_R15B, i8}, + + {X86_REG_AX, i16}, + {X86_REG_CX, i16}, + {X86_REG_DX, i16}, + {X86_REG_BP, i16}, + {X86_REG_BX, i16}, + {X86_REG_DI, i16}, + {X86_REG_SP, i16}, + {X86_REG_SI, i16}, + {X86_REG_SS, i16}, + {X86_REG_CS, i16}, + {X86_REG_DS, i16}, + {X86_REG_ES, i16}, + {X86_REG_FS, i16}, + {X86_REG_GS, i16}, + {X86_REG_R8W, i16}, + {X86_REG_R9W, i16}, + {X86_REG_R10W, i16}, + {X86_REG_R11W, i16}, + {X86_REG_R12W, i16}, + {X86_REG_R13W, i16}, + {X86_REG_R14W, i16}, + {X86_REG_R15W, i16}, + {X86_REG_IP, i16}, + + {X86_REG_EAX, i32}, + {X86_REG_EBP, i32}, + {X86_REG_EBX, i32}, + {X86_REG_ECX, i32}, + {X86_REG_EDI, i32}, + {X86_REG_EDX, i32}, + {X86_REG_ESI, i32}, + {X86_REG_ESP, i32}, + {X86_REG_R8D, i32}, + {X86_REG_R9D, i32}, + {X86_REG_R10D, i32}, + {X86_REG_R11D, i32}, + {X86_REG_R12D, i32}, + {X86_REG_R13D, i32}, + {X86_REG_R14D, i32}, + {X86_REG_R15D, i32}, + {X86_REG_EIP, i32}, + {X86_REG_EIZ, i32}, + + {X86_REG_RAX, i64}, + {X86_REG_RBP, i64}, + {X86_REG_RBX, i64}, + {X86_REG_RCX, i64}, + {X86_REG_RDI, i64}, + {X86_REG_RDX, i64}, + {X86_REG_RIP, i64}, + {X86_REG_RIZ, i64}, + {X86_REG_RSI, i64}, + {X86_REG_RSP, i64}, + {X86_REG_R8, i64}, + {X86_REG_R9, i64}, + {X86_REG_R10, i64}, + {X86_REG_R11, i64}, + {X86_REG_R12, i64}, + {X86_REG_R13, i64}, + {X86_REG_R14, i64}, + {X86_REG_R15, i64}, + + {X86_REG_ST0, fp80}, + {X86_REG_ST1, fp80}, + {X86_REG_ST2, fp80}, + {X86_REG_ST3, fp80}, + {X86_REG_ST4, fp80}, + {X86_REG_ST5, fp80}, + {X86_REG_ST6, fp80}, + {X86_REG_ST7, fp80}, + + {X86_REG_FP0, fp64}, + {X86_REG_FP1, fp64}, + {X86_REG_FP2, fp64}, + {X86_REG_FP3, fp64}, + {X86_REG_FP4, fp64}, + {X86_REG_FP5, fp64}, + {X86_REG_FP6, fp64}, + {X86_REG_FP7, fp64}, + + {X86_REG_EFLAGS, defTy}, + {X86_REG_DR0, defTy}, + {X86_REG_DR1, defTy}, + {X86_REG_DR2, defTy}, + {X86_REG_DR3, defTy}, + {X86_REG_DR4, defTy}, + {X86_REG_DR5, defTy}, + {X86_REG_DR6, defTy}, + {X86_REG_DR7, defTy}, + {X86_REG_DR8, defTy}, + {X86_REG_DR9, defTy}, + {X86_REG_DR10, defTy}, + {X86_REG_DR11, defTy}, + {X86_REG_DR12, defTy}, + {X86_REG_DR13, defTy}, + {X86_REG_DR14, defTy}, + {X86_REG_DR15, defTy}, + + {X86_REG_CR0, defTy}, + {X86_REG_CR1, defTy}, + {X86_REG_CR2, defTy}, + {X86_REG_CR3, defTy}, + {X86_REG_CR4, defTy}, + {X86_REG_CR5, defTy}, + {X86_REG_CR6, defTy}, + {X86_REG_CR7, defTy}, + {X86_REG_CR8, defTy}, + {X86_REG_CR9, defTy}, + {X86_REG_CR10, defTy}, + {X86_REG_CR11, defTy}, + {X86_REG_CR12, defTy}, + {X86_REG_CR13, defTy}, + {X86_REG_CR14, defTy}, + {X86_REG_CR15, defTy}, + + {X86_REG_FPSW, defTy}, + + // opmask registers (AVX-512) + {X86_REG_K0, i64}, + {X86_REG_K1, i64}, + {X86_REG_K2, i64}, + {X86_REG_K3, i64}, + {X86_REG_K4, i64}, + {X86_REG_K5, i64}, + {X86_REG_K6, i64}, + {X86_REG_K7, i64}, + + // MMX + {X86_REG_MM0, i64}, + {X86_REG_MM1, i64}, + {X86_REG_MM2, i64}, + {X86_REG_MM3, i64}, + {X86_REG_MM4, i64}, + {X86_REG_MM5, i64}, + {X86_REG_MM6, i64}, + {X86_REG_MM7, i64}, + + // XMM + {X86_REG_XMM0, i128}, + {X86_REG_XMM1, i128}, + {X86_REG_XMM2, i128}, + {X86_REG_XMM3, i128}, + {X86_REG_XMM4, i128}, + {X86_REG_XMM5, i128}, + {X86_REG_XMM6, i128}, + {X86_REG_XMM7, i128}, + {X86_REG_XMM8, i128}, + {X86_REG_XMM9, i128}, + {X86_REG_XMM10, i128}, + {X86_REG_XMM11, i128}, + {X86_REG_XMM12, i128}, + {X86_REG_XMM13, i128}, + {X86_REG_XMM14, i128}, + {X86_REG_XMM15, i128}, + {X86_REG_XMM16, i128}, + {X86_REG_XMM17, i128}, + {X86_REG_XMM18, i128}, + {X86_REG_XMM19, i128}, + {X86_REG_XMM20, i128}, + {X86_REG_XMM21, i128}, + {X86_REG_XMM22, i128}, + {X86_REG_XMM23, i128}, + {X86_REG_XMM24, i128}, + {X86_REG_XMM25, i128}, + {X86_REG_XMM26, i128}, + {X86_REG_XMM27, i128}, + {X86_REG_XMM28, i128}, + {X86_REG_XMM29, i128}, + {X86_REG_XMM30, i128}, + {X86_REG_XMM31, i128}, + + // YMM + {X86_REG_YMM0, i256}, + {X86_REG_YMM1, i256}, + {X86_REG_YMM2, i256}, + {X86_REG_YMM3, i256}, + {X86_REG_YMM4, i256}, + {X86_REG_YMM5, i256}, + {X86_REG_YMM6, i256}, + {X86_REG_YMM7, i256}, + {X86_REG_YMM8, i256}, + {X86_REG_YMM9, i256}, + {X86_REG_YMM10, i256}, + {X86_REG_YMM11, i256}, + {X86_REG_YMM12, i256}, + {X86_REG_YMM13, i256}, + {X86_REG_YMM14, i256}, + {X86_REG_YMM15, i256}, + {X86_REG_YMM16, i256}, + {X86_REG_YMM17, i256}, + {X86_REG_YMM18, i256}, + {X86_REG_YMM19, i256}, + {X86_REG_YMM20, i256}, + {X86_REG_YMM21, i256}, + {X86_REG_YMM22, i256}, + {X86_REG_YMM23, i256}, + {X86_REG_YMM24, i256}, + {X86_REG_YMM25, i256}, + {X86_REG_YMM26, i256}, + {X86_REG_YMM27, i256}, + {X86_REG_YMM28, i256}, + {X86_REG_YMM29, i256}, + {X86_REG_YMM30, i256}, + {X86_REG_YMM31, i256}, + + // ZMM + {X86_REG_ZMM0, i512}, + {X86_REG_ZMM1, i512}, + {X86_REG_ZMM2, i512}, + {X86_REG_ZMM3, i512}, + {X86_REG_ZMM4, i512}, + {X86_REG_ZMM5, i512}, + {X86_REG_ZMM6, i512}, + {X86_REG_ZMM7, i512}, + {X86_REG_ZMM8, i512}, + {X86_REG_ZMM9, i512}, + {X86_REG_ZMM10, i512}, + {X86_REG_ZMM11, i512}, + {X86_REG_ZMM12, i512}, + {X86_REG_ZMM13, i512}, + {X86_REG_ZMM14, i512}, + {X86_REG_ZMM15, i512}, + {X86_REG_ZMM16, i512}, + {X86_REG_ZMM17, i512}, + {X86_REG_ZMM18, i512}, + {X86_REG_ZMM19, i512}, + {X86_REG_ZMM20, i512}, + {X86_REG_ZMM21, i512}, + {X86_REG_ZMM22, i512}, + {X86_REG_ZMM23, i512}, + {X86_REG_ZMM24, i512}, + {X86_REG_ZMM25, i512}, + {X86_REG_ZMM26, i512}, + {X86_REG_ZMM27, i512}, + {X86_REG_ZMM28, i512}, + {X86_REG_ZMM29, i512}, + {X86_REG_ZMM30, i512}, + {X86_REG_ZMM31, i512}, + + // x86_reg_rflags + // + {X86_REG_CF, i1}, + {X86_REG_PF, i1}, + {X86_REG_AF, i1}, + {X86_REG_ZF, i1}, + {X86_REG_SF, i1}, + {X86_REG_TF, i1}, + {X86_REG_IF, i1}, + {X86_REG_DF, i1}, + {X86_REG_OF, i1}, + {X86_REG_IOPL, i2}, + {X86_REG_NT, i1}, + {X86_REG_RF, i1}, + {X86_REG_VM, i1}, + {X86_REG_AC, i1}, + {X86_REG_VIF, i1}, + {X86_REG_VIP, i1}, + {X86_REG_ID, i1}, + + // x87_reg_status + // + {X87_REG_IE, i1}, + {X87_REG_DE, i1}, + {X87_REG_ZE, i1}, + {X87_REG_OE, i1}, + {X87_REG_UE, i1}, + {X87_REG_PE, i1}, + {X87_REG_SF, i1}, + {X87_REG_ES, i1}, + {X87_REG_C0, i1}, + {X87_REG_C1, i1}, + {X87_REG_C2, i1}, + {X87_REG_C3, i1}, + {X87_REG_TOP, i3}, + {X87_REG_B, i1}, + + // x87_reg_control + // + {X87_REG_IM, i1}, + {X87_REG_DM, i1}, + {X87_REG_ZM, i1}, + {X87_REG_OM, i1}, + {X87_REG_UM, i1}, + {X87_REG_PM, i1}, + {X87_REG_PC, i2}, + {X87_REG_RC, i2}, + {X87_REG_X, i1}, + }; + + _reg2type = std::move(r2t); +} + +void Capstone2LlvmIrTranslatorX86_impl::initializePseudoCallInstructionIDs() +{ + _callInsnIds = + { + X86_INS_CALL, + X86_INS_LCALL, + }; + + _returnInsnIds = + { + X86_INS_RET, + X86_INS_RETF, + X86_INS_RETFQ + }; + + _branchInsnIds = + { + X86_INS_JMP, + X86_INS_LJMP, + }; + + _condBranchInsnIds = + { + X86_INS_JCXZ, + X86_INS_JECXZ, + X86_INS_JRCXZ, + // + X86_INS_LOOP, + X86_INS_LOOPE, + X86_INS_LOOPNE, + // + X86_INS_JAE, + X86_INS_JA, + X86_INS_JBE, + X86_INS_JB, + X86_INS_JE, + X86_INS_JGE, + X86_INS_JG, + X86_INS_JLE, + X86_INS_JL, + X86_INS_JNE, + X86_INS_JNO, + X86_INS_JNP, + X86_INS_JNS, + X86_INS_JO, + X86_INS_JP, + X86_INS_JS, + }; + + _controlFlowInsnIds = + { + // Currently, all instructions can be categorized based on their + // IDs alone. + }; +} + +// +//============================================================================== +// x86-specific methods. +//============================================================================== +// + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMapToOther( + const std::vector& rs, + x86_reg other) +{ + for (auto r : rs) + { + if (r >= _reg2parentMap.size()) + { + throw GenericError("Register out of range."); + } + _reg2parentMap[r] = other; + } +} + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap() +{ + switch (_origBasicMode) + { + case CS_MODE_16: initializeRegistersParentMap16(); break; + case CS_MODE_32: initializeRegistersParentMap32(); break; + case CS_MODE_64: initializeRegistersParentMap64(); break; + default: + { + throw GenericError("Unhandled mode in " + "initializeRegistersParentMap()."); + break; + } + } +} + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap16() +{ + // Last element in vector is its own parent. + std::vector> rss = + { + {X86_REG_AH, X86_REG_AL, X86_REG_AX}, + {X86_REG_CH, X86_REG_CL, X86_REG_CX}, + {X86_REG_DH, X86_REG_DL, X86_REG_DX}, + {X86_REG_BH, X86_REG_BL, X86_REG_BX}, + {X86_REG_SPL, X86_REG_SP}, + {X86_REG_BPL, X86_REG_BP}, + {X86_REG_SIL, X86_REG_SI}, + {X86_REG_DIL, X86_REG_DI}, + {X86_REG_IP}, + }; + + for (std::vector& rs : rss) + { + initializeRegistersParentMapToOther(rs, rs.back()); + } +} + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap32() +{ + // Last element in vector is its own parent. + std::vector> rss = + { + {X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_EAX}, + {X86_REG_CH, X86_REG_CL, X86_REG_CX, X86_REG_ECX}, + {X86_REG_DH, X86_REG_DL, X86_REG_DX, X86_REG_EDX}, + {X86_REG_BH, X86_REG_BL, X86_REG_BX, X86_REG_EBX}, + {X86_REG_SPL, X86_REG_SP, X86_REG_ESP}, + {X86_REG_BPL, X86_REG_BP, X86_REG_EBP}, + {X86_REG_SIL, X86_REG_SI, X86_REG_ESI}, + {X86_REG_DIL, X86_REG_DI, X86_REG_EDI}, + {X86_REG_IP, X86_REG_EIP}, + {X86_REG_EIZ}, + }; + + for (std::vector& rs : rss) + { + initializeRegistersParentMapToOther(rs, rs.back()); + } +} + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap64() +{ + // Last element in vector is its own parent. + std::vector> rss = + { + {X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_EAX, X86_REG_RAX}, + {X86_REG_CH, X86_REG_CL, X86_REG_CX, X86_REG_ECX, X86_REG_RCX}, + {X86_REG_DH, X86_REG_DL, X86_REG_DX, X86_REG_EDX, X86_REG_RDX}, + {X86_REG_BH, X86_REG_BL, X86_REG_BX, X86_REG_EBX, X86_REG_RBX}, + {X86_REG_SPL, X86_REG_SP, X86_REG_ESP, X86_REG_RSP}, + {X86_REG_BPL, X86_REG_BP, X86_REG_EBP, X86_REG_RBP}, + {X86_REG_SIL, X86_REG_SI, X86_REG_ESI, X86_REG_RSI}, + {X86_REG_DIL, X86_REG_DI, X86_REG_EDI, X86_REG_RDI}, + {X86_REG_IP, X86_REG_EIP, X86_REG_RIP}, + {X86_REG_EIZ, X86_REG_RIZ}, + {X86_REG_R8B, X86_REG_R8W, X86_REG_R8D, X86_REG_R8}, + {X86_REG_R9B, X86_REG_R9W, X86_REG_R9D, X86_REG_R9}, + {X86_REG_R10B, X86_REG_R10W, X86_REG_R10D, X86_REG_R10}, + {X86_REG_R11B, X86_REG_R11W, X86_REG_R11D, X86_REG_R11}, + {X86_REG_R12B, X86_REG_R12W, X86_REG_R12D, X86_REG_R12}, + {X86_REG_R13B, X86_REG_R13W, X86_REG_R13D, X86_REG_R13}, + {X86_REG_R14B, X86_REG_R14W, X86_REG_R14D, X86_REG_R14}, + {X86_REG_R15B, X86_REG_R15W, X86_REG_R15D, X86_REG_R15} + }; + + for (std::vector& rs : rss) + { + initializeRegistersParentMapToOther(rs, rs.back()); + } +} + +// +//============================================================================== +// Instruction translation map initialization. +//============================================================================== +// + +std::map< + std::size_t, + void (Capstone2LlvmIrTranslatorX86_impl::*)( + cs_insn* i, + cs_x86*, + llvm::IRBuilder<>&)> +Capstone2LlvmIrTranslatorX86_impl::_i2fm = +{ + {X86_INS_INVALID, nullptr}, + + {X86_INS_AAA, &Capstone2LlvmIrTranslatorX86_impl::translateAaa}, + {X86_INS_AAD, &Capstone2LlvmIrTranslatorX86_impl::translateAad}, + {X86_INS_AAM, &Capstone2LlvmIrTranslatorX86_impl::translateAam}, + {X86_INS_AAS, &Capstone2LlvmIrTranslatorX86_impl::translateAaa}, + {X86_INS_FABS, &Capstone2LlvmIrTranslatorX86_impl::translateFabs}, + {X86_INS_ADC, &Capstone2LlvmIrTranslatorX86_impl::translateAdc}, + {X86_INS_ADCX, &Capstone2LlvmIrTranslatorX86_impl::translateAdc}, + {X86_INS_ADD, &Capstone2LlvmIrTranslatorX86_impl::translateAdd}, + {X86_INS_ADDPD, nullptr}, + {X86_INS_ADDPS, nullptr}, + {X86_INS_ADDSD, nullptr}, + {X86_INS_ADDSS, nullptr}, + {X86_INS_ADDSUBPD, nullptr}, + {X86_INS_ADDSUBPS, nullptr}, + {X86_INS_FADD, &Capstone2LlvmIrTranslatorX86_impl::translateFadd}, + {X86_INS_FIADD, &Capstone2LlvmIrTranslatorX86_impl::translateFadd}, + {X86_INS_ADOX, &Capstone2LlvmIrTranslatorX86_impl::translateAdc}, + {X86_INS_AESDECLAST, nullptr}, + {X86_INS_AESDEC, nullptr}, + {X86_INS_AESENCLAST, nullptr}, + {X86_INS_AESENC, nullptr}, + {X86_INS_AESIMC, nullptr}, + {X86_INS_AESKEYGENASSIST, nullptr}, + {X86_INS_AND, &Capstone2LlvmIrTranslatorX86_impl::translateAnd}, + {X86_INS_ANDN, nullptr}, + {X86_INS_ANDNPD, nullptr}, + {X86_INS_ANDNPS, nullptr}, + {X86_INS_ANDPD, nullptr}, + {X86_INS_ANDPS, nullptr}, + {X86_INS_ARPL, nullptr}, + {X86_INS_BEXTR, nullptr}, + {X86_INS_BLCFILL, nullptr}, + {X86_INS_BLCI, nullptr}, + {X86_INS_BLCIC, nullptr}, + {X86_INS_BLCMSK, nullptr}, + {X86_INS_BLCS, nullptr}, + {X86_INS_BLENDPD, nullptr}, + {X86_INS_BLENDPS, nullptr}, + {X86_INS_BLENDVPD, nullptr}, + {X86_INS_BLENDVPS, nullptr}, + {X86_INS_BLSFILL, nullptr}, + {X86_INS_BLSI, nullptr}, + {X86_INS_BLSIC, nullptr}, + {X86_INS_BLSMSK, nullptr}, + {X86_INS_BLSR, nullptr}, + {X86_INS_BOUND, nullptr}, + {X86_INS_BSF, &Capstone2LlvmIrTranslatorX86_impl::translateBsf}, + {X86_INS_BSR, &Capstone2LlvmIrTranslatorX86_impl::translateBsf}, + {X86_INS_BSWAP, &Capstone2LlvmIrTranslatorX86_impl::translateBswap}, + {X86_INS_BT, &Capstone2LlvmIrTranslatorX86_impl::translateBt}, + {X86_INS_BTC, &Capstone2LlvmIrTranslatorX86_impl::translateBtc}, + {X86_INS_BTR, &Capstone2LlvmIrTranslatorX86_impl::translateBtr}, + {X86_INS_BTS, &Capstone2LlvmIrTranslatorX86_impl::translateBts}, + {X86_INS_BZHI, nullptr}, + {X86_INS_BNDMK, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_BNDCL, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_BNDCU, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_BNDMOV, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_BNDLDX, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_BNDSTX, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_CALL, &Capstone2LlvmIrTranslatorX86_impl::translateCall}, + {X86_INS_CBW, &Capstone2LlvmIrTranslatorX86_impl::translateCbw}, + {X86_INS_CDQ, &Capstone2LlvmIrTranslatorX86_impl::translateCdq}, + {X86_INS_CDQE, &Capstone2LlvmIrTranslatorX86_impl::translateCdqe}, + {X86_INS_FCHS, &Capstone2LlvmIrTranslatorX86_impl::translateFchs}, + {X86_INS_CLAC, nullptr}, + {X86_INS_CLC, &Capstone2LlvmIrTranslatorX86_impl::translateClc}, + {X86_INS_CLD, &Capstone2LlvmIrTranslatorX86_impl::translateCld}, + {X86_INS_CLFLUSH, nullptr}, + {X86_INS_CLFLUSHOPT, nullptr}, + {X86_INS_CLGI, nullptr}, + {X86_INS_CLI, &Capstone2LlvmIrTranslatorX86_impl::translateCli}, + {X86_INS_CLTS, nullptr}, + {X86_INS_CLWB, nullptr}, + {X86_INS_CMC, &Capstone2LlvmIrTranslatorX86_impl::translateCmc}, + {X86_INS_CMOVA, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVAE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVB, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVBE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_FCMOVBE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_FCMOVB, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_CMOVE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_FCMOVE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_CMOVG, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVGE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVL, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVLE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_FCMOVNBE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_FCMOVNB, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_CMOVNE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_FCMOVNE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_CMOVNO, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVNP, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_FCMOVNU, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_CMOVNS, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVO, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVP, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_FCMOVU, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_CMOVS, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMP, &Capstone2LlvmIrTranslatorX86_impl::translateSub}, + {X86_INS_CMPSB, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, + {X86_INS_CMPSQ, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, + {X86_INS_CMPSW, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, + {X86_INS_CMPXCHG16B, &Capstone2LlvmIrTranslatorX86_impl::translateCmpxchg16b}, + {X86_INS_CMPXCHG, &Capstone2LlvmIrTranslatorX86_impl::translateCmpxchg}, + {X86_INS_CMPXCHG8B, &Capstone2LlvmIrTranslatorX86_impl::translateCmpxchg8b}, + {X86_INS_COMISD, nullptr}, + {X86_INS_COMISS, nullptr}, + {X86_INS_FCOMP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FCOMPI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FCOMI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FCOM, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FCOS, &Capstone2LlvmIrTranslatorX86_impl::translateFcos}, + {X86_INS_CPUID, &Capstone2LlvmIrTranslatorX86_impl::translateCpuid}, + {X86_INS_CQO, &Capstone2LlvmIrTranslatorX86_impl::translateCqo}, + {X86_INS_CRC32, nullptr}, + {X86_INS_CVTDQ2PD, nullptr}, + {X86_INS_CVTDQ2PS, nullptr}, + {X86_INS_CVTPD2DQ, nullptr}, + {X86_INS_CVTPD2PS, nullptr}, + {X86_INS_CVTPS2DQ, nullptr}, + {X86_INS_CVTPS2PD, nullptr}, + {X86_INS_CVTSD2SI, nullptr}, + {X86_INS_CVTSD2SS, nullptr}, + {X86_INS_CVTSI2SD, nullptr}, + {X86_INS_CVTSI2SS, nullptr}, + {X86_INS_CVTSS2SD, nullptr}, + {X86_INS_CVTSS2SI, nullptr}, + {X86_INS_CVTTPD2DQ, nullptr}, + {X86_INS_CVTTPS2DQ, nullptr}, + {X86_INS_CVTTSD2SI, nullptr}, + {X86_INS_CVTTSS2SI, nullptr}, + {X86_INS_CWD, &Capstone2LlvmIrTranslatorX86_impl::translateCwd}, + {X86_INS_CWDE, &Capstone2LlvmIrTranslatorX86_impl::translateCwde}, + {X86_INS_DAA, &Capstone2LlvmIrTranslatorX86_impl::translateDaaDas}, + {X86_INS_DAS, &Capstone2LlvmIrTranslatorX86_impl::translateDaaDas}, + {X86_INS_DATA16, nullptr}, + {X86_INS_DEC, &Capstone2LlvmIrTranslatorX86_impl::translateDec}, + {X86_INS_DIV, &Capstone2LlvmIrTranslatorX86_impl::translateDiv}, + {X86_INS_DIVPD, nullptr}, + {X86_INS_DIVPS, nullptr}, + {X86_INS_FDIVR, &Capstone2LlvmIrTranslatorX86_impl::translateFdivr}, + {X86_INS_FIDIVR, &Capstone2LlvmIrTranslatorX86_impl::translateFdivr}, + {X86_INS_FDIVRP, &Capstone2LlvmIrTranslatorX86_impl::translateFdivr}, + {X86_INS_DIVSD, nullptr}, + {X86_INS_DIVSS, nullptr}, + {X86_INS_FDIV, &Capstone2LlvmIrTranslatorX86_impl::translateFdiv}, + {X86_INS_FIDIV, &Capstone2LlvmIrTranslatorX86_impl::translateFdiv}, + {X86_INS_FDIVP, &Capstone2LlvmIrTranslatorX86_impl::translateFdiv}, + {X86_INS_DPPD, nullptr}, + {X86_INS_DPPS, nullptr}, + {X86_INS_RET, &Capstone2LlvmIrTranslatorX86_impl::translateRet}, + {X86_INS_ENCLS, nullptr}, + {X86_INS_ENCLU, nullptr}, + {X86_INS_ENTER, &Capstone2LlvmIrTranslatorX86_impl::translateEnter}, + {X86_INS_EXTRACTPS, nullptr}, + {X86_INS_EXTRQ, nullptr}, + {X86_INS_F2XM1, &Capstone2LlvmIrTranslatorX86_impl::translateF2xm1}, + {X86_INS_LCALL, &Capstone2LlvmIrTranslatorX86_impl::translateLcall}, + {X86_INS_LJMP, &Capstone2LlvmIrTranslatorX86_impl::translateLjmp}, + {X86_INS_FBLD, &Capstone2LlvmIrTranslatorX86_impl::translateFbld}, + {X86_INS_FBSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFbstp}, + {X86_INS_FCOMPP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FDECSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFdecstp}, + {X86_INS_FEMMS, nullptr}, + {X86_INS_FFREE, &Capstone2LlvmIrTranslatorX86_impl::translateFfree}, + {X86_INS_FICOM, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FICOMP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FINCSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFincstp}, + {X86_INS_FLDCW, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_FLDENV, &Capstone2LlvmIrTranslatorX86_impl::translatePseudoAsmFncOp0}, + {X86_INS_FLDL2E, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FLDL2T, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FLDLG2, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FLDLN2, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FLDPI, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FNCLEX, &Capstone2LlvmIrTranslatorX86_impl::translateFnclex}, + {X86_INS_FNINIT, &Capstone2LlvmIrTranslatorX86_impl::translateFninit}, + {X86_INS_FNOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_FNSTCW, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_FNSTSW, &Capstone2LlvmIrTranslatorX86_impl::translateFnstsw}, + {X86_INS_FPATAN, &Capstone2LlvmIrTranslatorX86_impl::translateFatan}, + {X86_INS_FPREM, &Capstone2LlvmIrTranslatorX86_impl::translateFprem}, + {X86_INS_FPREM1, &Capstone2LlvmIrTranslatorX86_impl::translateFprem}, + {X86_INS_FPTAN, &Capstone2LlvmIrTranslatorX86_impl::translateFtan}, + {X86_INS_FFREEP, nullptr}, + {X86_INS_FRNDINT, &Capstone2LlvmIrTranslatorX86_impl::translateFrndint}, + {X86_INS_FRSTOR, &Capstone2LlvmIrTranslatorX86_impl::translateFrstor}, + {X86_INS_FNSAVE, &Capstone2LlvmIrTranslatorX86_impl::translateFnsave}, + {X86_INS_FSCALE, &Capstone2LlvmIrTranslatorX86_impl::translateFscale}, + {X86_INS_FSETPM, nullptr}, + {X86_INS_FSINCOS, &Capstone2LlvmIrTranslatorX86_impl::translateFsincos}, + {X86_INS_FNSTENV, &Capstone2LlvmIrTranslatorX86_impl::translateFnstenv}, + {X86_INS_FXAM, &Capstone2LlvmIrTranslatorX86_impl::translateFxam}, + {X86_INS_FXRSTOR, &Capstone2LlvmIrTranslatorX86_impl::translateFxstor}, + {X86_INS_FXRSTOR64, &Capstone2LlvmIrTranslatorX86_impl::translateFxstor}, + {X86_INS_FXSAVE, &Capstone2LlvmIrTranslatorX86_impl::translateFxsave}, + {X86_INS_FXSAVE64, &Capstone2LlvmIrTranslatorX86_impl::translateFxsave}, + {X86_INS_FXTRACT, &Capstone2LlvmIrTranslatorX86_impl::translateFxtract}, + {X86_INS_FYL2X, &Capstone2LlvmIrTranslatorX86_impl::translateFyl2x}, + {X86_INS_FYL2XP1, &Capstone2LlvmIrTranslatorX86_impl::translateFyl2x}, + {X86_INS_MOVAPD, nullptr}, + {X86_INS_MOVAPS, nullptr}, + {X86_INS_ORPD, nullptr}, + {X86_INS_ORPS, nullptr}, + {X86_INS_VMOVAPD, nullptr}, + {X86_INS_VMOVAPS, nullptr}, + {X86_INS_XORPD, nullptr}, + {X86_INS_XORPS, nullptr}, + {X86_INS_GETSEC, nullptr}, + {X86_INS_HADDPD, nullptr}, + {X86_INS_HADDPS, nullptr}, + {X86_INS_HLT, nullptr}, + {X86_INS_HSUBPD, nullptr}, + {X86_INS_HSUBPS, nullptr}, + {X86_INS_IDIV, &Capstone2LlvmIrTranslatorX86_impl::translateDiv}, + {X86_INS_FILD, &Capstone2LlvmIrTranslatorX86_impl::translateFld}, + {X86_INS_IMUL, &Capstone2LlvmIrTranslatorX86_impl::translateImul}, + {X86_INS_IN, nullptr}, + {X86_INS_INC, &Capstone2LlvmIrTranslatorX86_impl::translateInc}, + {X86_INS_INSB, &Capstone2LlvmIrTranslatorX86_impl::translateIns}, + {X86_INS_INSERTPS, nullptr}, + {X86_INS_INSERTQ, nullptr}, + {X86_INS_INSD, &Capstone2LlvmIrTranslatorX86_impl::translateIns}, + {X86_INS_INSW, &Capstone2LlvmIrTranslatorX86_impl::translateIns}, + {X86_INS_INT, nullptr}, + {X86_INS_INT1, nullptr}, + {X86_INS_INT3, nullptr}, + {X86_INS_INTO, nullptr}, + {X86_INS_INVD, nullptr}, + {X86_INS_INVEPT, nullptr}, + {X86_INS_INVLPG, nullptr}, + {X86_INS_INVLPGA, nullptr}, + {X86_INS_INVPCID, nullptr}, + {X86_INS_INVVPID, nullptr}, + {X86_INS_IRET, nullptr}, + {X86_INS_IRETD, nullptr}, + {X86_INS_IRETQ, nullptr}, + {X86_INS_FISTTP, &Capstone2LlvmIrTranslatorX86_impl::translateFist}, + {X86_INS_FIST, &Capstone2LlvmIrTranslatorX86_impl::translateFist}, + {X86_INS_FISTP, &Capstone2LlvmIrTranslatorX86_impl::translateFist}, + {X86_INS_UCOMISD, nullptr}, + {X86_INS_UCOMISS, nullptr}, + {X86_INS_VCOMISD, nullptr}, + {X86_INS_VCOMISS, nullptr}, + {X86_INS_VCVTSD2SS, nullptr}, + {X86_INS_VCVTSI2SD, nullptr}, + {X86_INS_VCVTSI2SS, nullptr}, + {X86_INS_VCVTSS2SD, nullptr}, + {X86_INS_VCVTTSD2SI, nullptr}, + {X86_INS_VCVTTSD2USI, nullptr}, + {X86_INS_VCVTTSS2SI, nullptr}, + {X86_INS_VCVTTSS2USI, nullptr}, + {X86_INS_VCVTUSI2SD, nullptr}, + {X86_INS_VCVTUSI2SS, nullptr}, + {X86_INS_VUCOMISD, nullptr}, + {X86_INS_VUCOMISS, nullptr}, + {X86_INS_JAE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JA, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JBE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JB, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JCXZ, &Capstone2LlvmIrTranslatorX86_impl::translateJecxz}, + {X86_INS_JECXZ, &Capstone2LlvmIrTranslatorX86_impl::translateJecxz}, + {X86_INS_JE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JGE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JG, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JLE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JL, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JMP, &Capstone2LlvmIrTranslatorX86_impl::translateJmp}, + {X86_INS_JNE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JNO, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JNP, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JNS, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JO, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JP, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JRCXZ, &Capstone2LlvmIrTranslatorX86_impl::translateJecxz}, + {X86_INS_JS, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_KANDB, nullptr}, + {X86_INS_KANDD, nullptr}, + {X86_INS_KANDNB, nullptr}, + {X86_INS_KANDND, nullptr}, + {X86_INS_KANDNQ, nullptr}, + {X86_INS_KANDNW, nullptr}, + {X86_INS_KANDQ, nullptr}, + {X86_INS_KANDW, nullptr}, + {X86_INS_KMOVB, nullptr}, + {X86_INS_KMOVD, nullptr}, + {X86_INS_KMOVQ, nullptr}, + {X86_INS_KMOVW, nullptr}, + {X86_INS_KNOTB, nullptr}, + {X86_INS_KNOTD, nullptr}, + {X86_INS_KNOTQ, nullptr}, + {X86_INS_KNOTW, nullptr}, + {X86_INS_KORB, nullptr}, + {X86_INS_KORD, nullptr}, + {X86_INS_KORQ, nullptr}, + {X86_INS_KORTESTB, nullptr}, + {X86_INS_KORTESTD, nullptr}, + {X86_INS_KORTESTQ, nullptr}, + {X86_INS_KORTESTW, nullptr}, + {X86_INS_KORW, nullptr}, + {X86_INS_KSHIFTLB, nullptr}, + {X86_INS_KSHIFTLD, nullptr}, + {X86_INS_KSHIFTLQ, nullptr}, + {X86_INS_KSHIFTLW, nullptr}, + {X86_INS_KSHIFTRB, nullptr}, + {X86_INS_KSHIFTRD, nullptr}, + {X86_INS_KSHIFTRQ, nullptr}, + {X86_INS_KSHIFTRW, nullptr}, + {X86_INS_KUNPCKBW, nullptr}, + {X86_INS_KXNORB, nullptr}, + {X86_INS_KXNORD, nullptr}, + {X86_INS_KXNORQ, nullptr}, + {X86_INS_KXNORW, nullptr}, + {X86_INS_KXORB, nullptr}, + {X86_INS_KXORD, nullptr}, + {X86_INS_KXORQ, nullptr}, + {X86_INS_KXORW, nullptr}, + {X86_INS_LAHF, &Capstone2LlvmIrTranslatorX86_impl::translateLahf}, + {X86_INS_LAR, nullptr}, + {X86_INS_LDDQU, nullptr}, + {X86_INS_LDMXCSR, nullptr}, + {X86_INS_LDS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, + {X86_INS_FLDZ, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FLD1, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FLD, &Capstone2LlvmIrTranslatorX86_impl::translateFld}, + {X86_INS_LEA, &Capstone2LlvmIrTranslatorX86_impl::translateLea}, + {X86_INS_LEAVE, &Capstone2LlvmIrTranslatorX86_impl::translateLeave}, + {X86_INS_LES, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, + {X86_INS_LFENCE, nullptr}, + {X86_INS_LFS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, + {X86_INS_LGDT, nullptr}, + {X86_INS_LGS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, + {X86_INS_LIDT, nullptr}, + {X86_INS_LLDT, nullptr}, + {X86_INS_LMSW, nullptr}, + {X86_INS_OR, &Capstone2LlvmIrTranslatorX86_impl::translateOr}, + {X86_INS_SUB, &Capstone2LlvmIrTranslatorX86_impl::translateSub}, + {X86_INS_XOR, &Capstone2LlvmIrTranslatorX86_impl::translateXor}, + {X86_INS_LODSB, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, + {X86_INS_LODSD, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, + {X86_INS_LODSQ, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, + {X86_INS_LODSW, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, + {X86_INS_LOOP, &Capstone2LlvmIrTranslatorX86_impl::translateLoop}, + {X86_INS_LOOPE, &Capstone2LlvmIrTranslatorX86_impl::translateLoop}, + {X86_INS_LOOPNE, &Capstone2LlvmIrTranslatorX86_impl::translateLoop}, + {X86_INS_RETF, &Capstone2LlvmIrTranslatorX86_impl::translateRet}, + {X86_INS_RETFQ, &Capstone2LlvmIrTranslatorX86_impl::translateRet}, + {X86_INS_LSL, nullptr}, + {X86_INS_LSS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, + {X86_INS_LTR, nullptr}, + {X86_INS_XADD, &Capstone2LlvmIrTranslatorX86_impl::translateAdd}, + {X86_INS_LZCNT, nullptr}, + {X86_INS_MASKMOVDQU, nullptr}, + {X86_INS_MAXPD, nullptr}, + {X86_INS_MAXPS, nullptr}, + {X86_INS_MAXSD, nullptr}, + {X86_INS_MAXSS, nullptr}, + {X86_INS_MFENCE, nullptr}, + {X86_INS_MINPD, nullptr}, + {X86_INS_MINPS, nullptr}, + {X86_INS_MINSD, nullptr}, + {X86_INS_MINSS, nullptr}, + {X86_INS_CVTPD2PI, nullptr}, + {X86_INS_CVTPI2PD, nullptr}, + {X86_INS_CVTPI2PS, nullptr}, + {X86_INS_CVTPS2PI, nullptr}, + {X86_INS_CVTTPD2PI, nullptr}, + {X86_INS_CVTTPS2PI, nullptr}, + {X86_INS_EMMS, nullptr}, + {X86_INS_MASKMOVQ, nullptr}, + {X86_INS_MOVD, nullptr}, + {X86_INS_MOVDQ2Q, nullptr}, + {X86_INS_MOVNTQ, nullptr}, + {X86_INS_MOVQ2DQ, nullptr}, + {X86_INS_MOVQ, nullptr}, + {X86_INS_PABSB, nullptr}, + {X86_INS_PABSD, nullptr}, + {X86_INS_PABSW, nullptr}, + {X86_INS_PACKSSDW, nullptr}, + {X86_INS_PACKSSWB, nullptr}, + {X86_INS_PACKUSWB, nullptr}, + {X86_INS_PADDB, nullptr}, + {X86_INS_PADDD, nullptr}, + {X86_INS_PADDQ, nullptr}, + {X86_INS_PADDSB, nullptr}, + {X86_INS_PADDSW, nullptr}, + {X86_INS_PADDUSB, nullptr}, + {X86_INS_PADDUSW, nullptr}, + {X86_INS_PADDW, nullptr}, + {X86_INS_PALIGNR, nullptr}, + {X86_INS_PANDN, nullptr}, + {X86_INS_PAND, nullptr}, + {X86_INS_PAVGB, nullptr}, + {X86_INS_PAVGW, nullptr}, + {X86_INS_PCMPEQB, nullptr}, + {X86_INS_PCMPEQD, nullptr}, + {X86_INS_PCMPEQW, nullptr}, + {X86_INS_PCMPGTB, nullptr}, + {X86_INS_PCMPGTD, nullptr}, + {X86_INS_PCMPGTW, nullptr}, + {X86_INS_PEXTRW, nullptr}, + {X86_INS_PHADDSW, nullptr}, + {X86_INS_PHADDW, nullptr}, + {X86_INS_PHADDD, nullptr}, + {X86_INS_PHSUBD, nullptr}, + {X86_INS_PHSUBSW, nullptr}, + {X86_INS_PHSUBW, nullptr}, + {X86_INS_PINSRW, nullptr}, + {X86_INS_PMADDUBSW, nullptr}, + {X86_INS_PMADDWD, nullptr}, + {X86_INS_PMAXSW, nullptr}, + {X86_INS_PMAXUB, nullptr}, + {X86_INS_PMINSW, nullptr}, + {X86_INS_PMINUB, nullptr}, + {X86_INS_PMOVMSKB, nullptr}, + {X86_INS_PMULHRSW, nullptr}, + {X86_INS_PMULHUW, nullptr}, + {X86_INS_PMULHW, nullptr}, + {X86_INS_PMULLW, nullptr}, + {X86_INS_PMULUDQ, nullptr}, + {X86_INS_POR, nullptr}, + {X86_INS_PSADBW, nullptr}, + {X86_INS_PSHUFB, nullptr}, + {X86_INS_PSHUFW, nullptr}, + {X86_INS_PSIGNB, nullptr}, + {X86_INS_PSIGND, nullptr}, + {X86_INS_PSIGNW, nullptr}, + {X86_INS_PSLLD, nullptr}, + {X86_INS_PSLLQ, nullptr}, + {X86_INS_PSLLW, nullptr}, + {X86_INS_PSRAD, nullptr}, + {X86_INS_PSRAW, nullptr}, + {X86_INS_PSRLD, nullptr}, + {X86_INS_PSRLQ, nullptr}, + {X86_INS_PSRLW, nullptr}, + {X86_INS_PSUBB, nullptr}, + {X86_INS_PSUBD, nullptr}, + {X86_INS_PSUBQ, nullptr}, + {X86_INS_PSUBSB, nullptr}, + {X86_INS_PSUBSW, nullptr}, + {X86_INS_PSUBUSB, nullptr}, + {X86_INS_PSUBUSW, nullptr}, + {X86_INS_PSUBW, nullptr}, + {X86_INS_PUNPCKHBW, nullptr}, + {X86_INS_PUNPCKHDQ, nullptr}, + {X86_INS_PUNPCKHWD, nullptr}, + {X86_INS_PUNPCKLBW, nullptr}, + {X86_INS_PUNPCKLDQ, nullptr}, + {X86_INS_PUNPCKLWD, nullptr}, + {X86_INS_PXOR, nullptr}, + {X86_INS_MONITOR, nullptr}, + {X86_INS_MONTMUL, nullptr}, + {X86_INS_MOV, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, + {X86_INS_MOVABS, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, + {X86_INS_MOVBE, nullptr}, + {X86_INS_MOVDDUP, nullptr}, + {X86_INS_MOVDQA, nullptr}, + {X86_INS_MOVDQU, nullptr}, + {X86_INS_MOVHLPS, nullptr}, + {X86_INS_MOVHPD, nullptr}, + {X86_INS_MOVHPS, nullptr}, + {X86_INS_MOVLHPS, nullptr}, + {X86_INS_MOVLPD, nullptr}, + {X86_INS_MOVLPS, nullptr}, + {X86_INS_MOVMSKPD, nullptr}, + {X86_INS_MOVMSKPS, nullptr}, + {X86_INS_MOVNTDQA, nullptr}, + {X86_INS_MOVNTDQ, nullptr}, + {X86_INS_MOVNTI, nullptr}, + {X86_INS_MOVNTPD, nullptr}, + {X86_INS_MOVNTPS, nullptr}, + {X86_INS_MOVNTSD, nullptr}, + {X86_INS_MOVNTSS, nullptr}, + {X86_INS_MOVSB, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, + {X86_INS_MOVSD, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, + {X86_INS_MOVSHDUP, nullptr}, + {X86_INS_MOVSLDUP, nullptr}, + {X86_INS_MOVSQ, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, + {X86_INS_MOVSS, nullptr}, + {X86_INS_MOVSW, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, + {X86_INS_MOVSX, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, + {X86_INS_MOVSXD, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, + {X86_INS_MOVUPD, nullptr}, + {X86_INS_MOVUPS, nullptr}, + {X86_INS_MOVZX, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, + {X86_INS_MPSADBW, nullptr}, + {X86_INS_MUL, &Capstone2LlvmIrTranslatorX86_impl::translateMul}, + {X86_INS_MULPD, nullptr}, + {X86_INS_MULPS, nullptr}, + {X86_INS_MULSD, nullptr}, + {X86_INS_MULSS, nullptr}, + {X86_INS_MULX, nullptr}, + {X86_INS_FMUL, &Capstone2LlvmIrTranslatorX86_impl::translateFmul}, + {X86_INS_FIMUL, &Capstone2LlvmIrTranslatorX86_impl::translateFmul}, + {X86_INS_FMULP, &Capstone2LlvmIrTranslatorX86_impl::translateFmul}, + {X86_INS_MWAIT, nullptr}, + {X86_INS_NEG, &Capstone2LlvmIrTranslatorX86_impl::translateNeg}, + {X86_INS_NOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_NOT, &Capstone2LlvmIrTranslatorX86_impl::translateNot}, + {X86_INS_OUT, nullptr}, + {X86_INS_OUTSB, &Capstone2LlvmIrTranslatorX86_impl::translateOuts}, + {X86_INS_OUTSD, &Capstone2LlvmIrTranslatorX86_impl::translateOuts}, + {X86_INS_OUTSW, &Capstone2LlvmIrTranslatorX86_impl::translateOuts}, + {X86_INS_PACKUSDW, nullptr}, + {X86_INS_PAUSE, nullptr}, + {X86_INS_PAVGUSB, nullptr}, + {X86_INS_PBLENDVB, nullptr}, + {X86_INS_PBLENDW, nullptr}, + {X86_INS_PCLMULQDQ, nullptr}, + {X86_INS_PCMPEQQ, nullptr}, + {X86_INS_PCMPESTRI, nullptr}, + {X86_INS_PCMPESTRM, nullptr}, + {X86_INS_PCMPGTQ, nullptr}, + {X86_INS_PCMPISTRI, nullptr}, + {X86_INS_PCMPISTRM, nullptr}, + {X86_INS_PDEP, nullptr}, + {X86_INS_PEXT, nullptr}, + {X86_INS_PEXTRB, nullptr}, + {X86_INS_PEXTRD, nullptr}, + {X86_INS_PEXTRQ, nullptr}, + {X86_INS_PF2ID, nullptr}, + {X86_INS_PF2IW, nullptr}, + {X86_INS_PFACC, nullptr}, + {X86_INS_PFADD, nullptr}, + {X86_INS_PFCMPEQ, nullptr}, + {X86_INS_PFCMPGE, nullptr}, + {X86_INS_PFCMPGT, nullptr}, + {X86_INS_PFMAX, nullptr}, + {X86_INS_PFMIN, nullptr}, + {X86_INS_PFMUL, nullptr}, + {X86_INS_PFNACC, nullptr}, + {X86_INS_PFPNACC, nullptr}, + {X86_INS_PFRCPIT1, nullptr}, + {X86_INS_PFRCPIT2, nullptr}, + {X86_INS_PFRCP, nullptr}, + {X86_INS_PFRSQIT1, nullptr}, + {X86_INS_PFRSQRT, nullptr}, + {X86_INS_PFSUBR, nullptr}, + {X86_INS_PFSUB, nullptr}, + {X86_INS_PHMINPOSUW, nullptr}, + {X86_INS_PI2FD, nullptr}, + {X86_INS_PI2FW, nullptr}, + {X86_INS_PINSRB, nullptr}, + {X86_INS_PINSRD, nullptr}, + {X86_INS_PINSRQ, nullptr}, + {X86_INS_PMAXSB, nullptr}, + {X86_INS_PMAXSD, nullptr}, + {X86_INS_PMAXUD, nullptr}, + {X86_INS_PMAXUW, nullptr}, + {X86_INS_PMINSB, nullptr}, + {X86_INS_PMINSD, nullptr}, + {X86_INS_PMINUD, nullptr}, + {X86_INS_PMINUW, nullptr}, + {X86_INS_PMOVSXBD, nullptr}, + {X86_INS_PMOVSXBQ, nullptr}, + {X86_INS_PMOVSXBW, nullptr}, + {X86_INS_PMOVSXDQ, nullptr}, + {X86_INS_PMOVSXWD, nullptr}, + {X86_INS_PMOVSXWQ, nullptr}, + {X86_INS_PMOVZXBD, nullptr}, + {X86_INS_PMOVZXBQ, nullptr}, + {X86_INS_PMOVZXBW, nullptr}, + {X86_INS_PMOVZXDQ, nullptr}, + {X86_INS_PMOVZXWD, nullptr}, + {X86_INS_PMOVZXWQ, nullptr}, + {X86_INS_PMULDQ, nullptr}, + {X86_INS_PMULHRW, nullptr}, + {X86_INS_PMULLD, nullptr}, + {X86_INS_POP, &Capstone2LlvmIrTranslatorX86_impl::translatePop}, + {X86_INS_POPAW, &Capstone2LlvmIrTranslatorX86_impl::translatePopa}, // X86_INS_POPAW == POPA + {X86_INS_POPAL, &Capstone2LlvmIrTranslatorX86_impl::translatePopa}, // X86_INS_POPAL == POPAD + {X86_INS_POPCNT, nullptr}, + {X86_INS_POPF, &Capstone2LlvmIrTranslatorX86_impl::translatePopEflags}, + {X86_INS_POPFD, &Capstone2LlvmIrTranslatorX86_impl::translatePopEflags}, + {X86_INS_POPFQ, &Capstone2LlvmIrTranslatorX86_impl::translatePopEflags}, + {X86_INS_PREFETCH, nullptr}, + {X86_INS_PREFETCHNTA, nullptr}, + {X86_INS_PREFETCHT0, nullptr}, + {X86_INS_PREFETCHT1, nullptr}, + {X86_INS_PREFETCHT2, nullptr}, + {X86_INS_PREFETCHW, nullptr}, + {X86_INS_PSHUFD, nullptr}, + {X86_INS_PSHUFHW, nullptr}, + {X86_INS_PSHUFLW, nullptr}, + {X86_INS_PSLLDQ, nullptr}, + {X86_INS_PSRLDQ, nullptr}, + {X86_INS_PSWAPD, nullptr}, + {X86_INS_PTEST, nullptr}, + {X86_INS_PUNPCKHQDQ, nullptr}, + {X86_INS_PUNPCKLQDQ, nullptr}, + {X86_INS_PUSH, &Capstone2LlvmIrTranslatorX86_impl::translatePush}, + {X86_INS_PUSHAW, &Capstone2LlvmIrTranslatorX86_impl::translatePusha}, // X86_INS_PUSHAW = PUSHA + {X86_INS_PUSHAL, &Capstone2LlvmIrTranslatorX86_impl::translatePusha}, // X86_INS_PUSHAL = PUSHAD + {X86_INS_PUSHF, &Capstone2LlvmIrTranslatorX86_impl::translatePushEflags}, + {X86_INS_PUSHFD, &Capstone2LlvmIrTranslatorX86_impl::translatePushEflags}, + {X86_INS_PUSHFQ, &Capstone2LlvmIrTranslatorX86_impl::translatePushEflags}, + {X86_INS_RCL, &Capstone2LlvmIrTranslatorX86_impl::translateRcl}, + {X86_INS_RCPPS, nullptr}, + {X86_INS_RCPSS, nullptr}, + {X86_INS_RCR, &Capstone2LlvmIrTranslatorX86_impl::translateRcr}, + {X86_INS_RDFSBASE, nullptr}, + {X86_INS_RDGSBASE, nullptr}, + {X86_INS_RDMSR, nullptr}, + {X86_INS_RDPMC, nullptr}, + {X86_INS_RDRAND, nullptr}, + {X86_INS_RDSEED, nullptr}, + {X86_INS_RDTSC, &Capstone2LlvmIrTranslatorX86_impl::translateRdtsc}, + {X86_INS_RDTSCP, &Capstone2LlvmIrTranslatorX86_impl::translateRdtscp}, + {X86_INS_ROL, &Capstone2LlvmIrTranslatorX86_impl::translateRol}, + {X86_INS_ROR, &Capstone2LlvmIrTranslatorX86_impl::translateRor}, + {X86_INS_RORX, nullptr}, + {X86_INS_ROUNDPD, nullptr}, + {X86_INS_ROUNDPS, nullptr}, + {X86_INS_ROUNDSD, nullptr}, + {X86_INS_ROUNDSS, nullptr}, + {X86_INS_RSM, nullptr}, + {X86_INS_RSQRTPS, nullptr}, + {X86_INS_RSQRTSS, nullptr}, + {X86_INS_SAHF, &Capstone2LlvmIrTranslatorX86_impl::translateSahf}, + {X86_INS_SAL, &Capstone2LlvmIrTranslatorX86_impl::translateShiftLeft}, + {X86_INS_SALC, &Capstone2LlvmIrTranslatorX86_impl::translateSalc}, + {X86_INS_SAR, &Capstone2LlvmIrTranslatorX86_impl::translateShiftRight}, + {X86_INS_SARX, nullptr}, + {X86_INS_SBB, &Capstone2LlvmIrTranslatorX86_impl::translateSbb}, + {X86_INS_SCASB, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, + {X86_INS_SCASD, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, + {X86_INS_SCASQ, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, + {X86_INS_SCASW, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, + {X86_INS_SETAE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETA, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETBE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETB, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETGE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETG, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETLE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETL, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETNE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETNO, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETNP, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETNS, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETO, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETP, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETS, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SFENCE, nullptr}, + {X86_INS_SGDT, nullptr}, + {X86_INS_SHA1MSG1, nullptr}, + {X86_INS_SHA1MSG2, nullptr}, + {X86_INS_SHA1NEXTE, nullptr}, + {X86_INS_SHA1RNDS4, nullptr}, + {X86_INS_SHA256MSG1, nullptr}, + {X86_INS_SHA256MSG2, nullptr}, + {X86_INS_SHA256RNDS2, nullptr}, + {X86_INS_SHL, &Capstone2LlvmIrTranslatorX86_impl::translateShiftLeft}, + {X86_INS_SHLD, &Capstone2LlvmIrTranslatorX86_impl::translateShld}, + {X86_INS_SHLX, nullptr}, + {X86_INS_SHR, &Capstone2LlvmIrTranslatorX86_impl::translateShiftRight}, + {X86_INS_SHRD, &Capstone2LlvmIrTranslatorX86_impl::translateShrd}, + {X86_INS_SHRX, nullptr}, + {X86_INS_SHUFPD, nullptr}, + {X86_INS_SHUFPS, nullptr}, + {X86_INS_SIDT, nullptr}, + {X86_INS_FSIN, &Capstone2LlvmIrTranslatorX86_impl::translateFsin}, + {X86_INS_SKINIT, nullptr}, + {X86_INS_SLDT, nullptr}, + {X86_INS_SMSW, nullptr}, + {X86_INS_SQRTPD, nullptr}, + {X86_INS_SQRTPS, nullptr}, + {X86_INS_SQRTSD, nullptr}, + {X86_INS_SQRTSS, nullptr}, + {X86_INS_FSQRT, &Capstone2LlvmIrTranslatorX86_impl::translateFsqrt}, + {X86_INS_STAC, nullptr}, + {X86_INS_STC, &Capstone2LlvmIrTranslatorX86_impl::translateStc}, + {X86_INS_STD, &Capstone2LlvmIrTranslatorX86_impl::translateStd}, + {X86_INS_STGI, nullptr}, + {X86_INS_STI, nullptr}, + {X86_INS_STMXCSR, nullptr}, + {X86_INS_STOSB, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, + {X86_INS_STOSD, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, + {X86_INS_STOSQ, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, + {X86_INS_STOSW, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, + {X86_INS_STR, nullptr}, + {X86_INS_FST, &Capstone2LlvmIrTranslatorX86_impl::translateFst}, + {X86_INS_FSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFst}, + {X86_INS_FSTPNCE, nullptr}, + {X86_INS_FXCH, &Capstone2LlvmIrTranslatorX86_impl::translateFxch}, + {X86_INS_SUBPD, nullptr}, + {X86_INS_SUBPS, nullptr}, + {X86_INS_FSUBR, &Capstone2LlvmIrTranslatorX86_impl::translateFsubr}, + {X86_INS_FISUBR, &Capstone2LlvmIrTranslatorX86_impl::translateFsubr}, + {X86_INS_FSUBRP, &Capstone2LlvmIrTranslatorX86_impl::translateFsubr}, + {X86_INS_SUBSD, nullptr}, + {X86_INS_SUBSS, nullptr}, + {X86_INS_FSUB, &Capstone2LlvmIrTranslatorX86_impl::translateFsub}, + {X86_INS_FISUB, &Capstone2LlvmIrTranslatorX86_impl::translateFsub}, + {X86_INS_FSUBP, &Capstone2LlvmIrTranslatorX86_impl::translateFsub}, + {X86_INS_SWAPGS, nullptr}, + {X86_INS_SYSCALL, nullptr}, + {X86_INS_SYSENTER, nullptr}, + {X86_INS_SYSEXIT, nullptr}, + {X86_INS_SYSRET, nullptr}, + {X86_INS_T1MSKC, nullptr}, + {X86_INS_TEST, &Capstone2LlvmIrTranslatorX86_impl::translateAnd}, + {X86_INS_UD2, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_FTST, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_TZCNT, nullptr}, + {X86_INS_TZMSK, nullptr}, + {X86_INS_FUCOMPI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FUCOMI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FUCOMPP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FUCOMP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FUCOM, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_UD1, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_UNPCKHPD, nullptr}, + {X86_INS_UNPCKHPS, nullptr}, + {X86_INS_UNPCKLPD, nullptr}, + {X86_INS_UNPCKLPS, nullptr}, + {X86_INS_VADDPD, nullptr}, + {X86_INS_VADDPS, nullptr}, + {X86_INS_VADDSD, nullptr}, + {X86_INS_VADDSS, nullptr}, + {X86_INS_VADDSUBPD, nullptr}, + {X86_INS_VADDSUBPS, nullptr}, + {X86_INS_VAESDECLAST, nullptr}, + {X86_INS_VAESDEC, nullptr}, + {X86_INS_VAESENCLAST, nullptr}, + {X86_INS_VAESENC, nullptr}, + {X86_INS_VAESIMC, nullptr}, + {X86_INS_VAESKEYGENASSIST, nullptr}, + {X86_INS_VALIGND, nullptr}, + {X86_INS_VALIGNQ, nullptr}, + {X86_INS_VANDNPD, nullptr}, + {X86_INS_VANDNPS, nullptr}, + {X86_INS_VANDPD, nullptr}, + {X86_INS_VANDPS, nullptr}, + {X86_INS_VBLENDMPD, nullptr}, + {X86_INS_VBLENDMPS, nullptr}, + {X86_INS_VBLENDPD, nullptr}, + {X86_INS_VBLENDPS, nullptr}, + {X86_INS_VBLENDVPD, nullptr}, + {X86_INS_VBLENDVPS, nullptr}, + {X86_INS_VBROADCASTF128, nullptr}, + {X86_INS_VBROADCASTI32X4, nullptr}, + {X86_INS_VBROADCASTI64X4, nullptr}, + {X86_INS_VBROADCASTSD, nullptr}, + {X86_INS_VBROADCASTSS, nullptr}, + {X86_INS_VCOMPRESSPD, nullptr}, + {X86_INS_VCOMPRESSPS, nullptr}, + {X86_INS_VCVTDQ2PD, nullptr}, + {X86_INS_VCVTDQ2PS, nullptr}, + {X86_INS_VCVTPD2DQ, nullptr}, + {X86_INS_VCVTPD2PS, nullptr}, + {X86_INS_VCVTPD2UDQ, nullptr}, + {X86_INS_VCVTPH2PS, nullptr}, + {X86_INS_VCVTPS2DQ, nullptr}, + {X86_INS_VCVTPS2PD, nullptr}, + {X86_INS_VCVTPS2PH, nullptr}, + {X86_INS_VCVTPS2UDQ, nullptr}, + {X86_INS_VCVTSD2SI, nullptr}, + {X86_INS_VCVTSD2USI, nullptr}, + {X86_INS_VCVTSS2SI, nullptr}, + {X86_INS_VCVTSS2USI, nullptr}, + {X86_INS_VCVTTPD2DQ, nullptr}, + {X86_INS_VCVTTPD2UDQ, nullptr}, + {X86_INS_VCVTTPS2DQ, nullptr}, + {X86_INS_VCVTTPS2UDQ, nullptr}, + {X86_INS_VCVTUDQ2PD, nullptr}, + {X86_INS_VCVTUDQ2PS, nullptr}, + {X86_INS_VDIVPD, nullptr}, + {X86_INS_VDIVPS, nullptr}, + {X86_INS_VDIVSD, nullptr}, + {X86_INS_VDIVSS, nullptr}, + {X86_INS_VDPPD, nullptr}, + {X86_INS_VDPPS, nullptr}, + {X86_INS_VERR, nullptr}, + {X86_INS_VERW, nullptr}, + {X86_INS_VEXP2PD, nullptr}, + {X86_INS_VEXP2PS, nullptr}, + {X86_INS_VEXPANDPD, nullptr}, + {X86_INS_VEXPANDPS, nullptr}, + {X86_INS_VEXTRACTF128, nullptr}, + {X86_INS_VEXTRACTF32X4, nullptr}, + {X86_INS_VEXTRACTF64X4, nullptr}, + {X86_INS_VEXTRACTI128, nullptr}, + {X86_INS_VEXTRACTI32X4, nullptr}, + {X86_INS_VEXTRACTI64X4, nullptr}, + {X86_INS_VEXTRACTPS, nullptr}, + {X86_INS_VFMADD132PD, nullptr}, + {X86_INS_VFMADD132PS, nullptr}, + {X86_INS_VFMADDPD, nullptr}, + {X86_INS_VFMADD213PD, nullptr}, + {X86_INS_VFMADD231PD, nullptr}, + {X86_INS_VFMADDPS, nullptr}, + {X86_INS_VFMADD213PS, nullptr}, + {X86_INS_VFMADD231PS, nullptr}, + {X86_INS_VFMADDSD, nullptr}, + {X86_INS_VFMADD213SD, nullptr}, + {X86_INS_VFMADD132SD, nullptr}, + {X86_INS_VFMADD231SD, nullptr}, + {X86_INS_VFMADDSS, nullptr}, + {X86_INS_VFMADD213SS, nullptr}, + {X86_INS_VFMADD132SS, nullptr}, + {X86_INS_VFMADD231SS, nullptr}, + {X86_INS_VFMADDSUB132PD, nullptr}, + {X86_INS_VFMADDSUB132PS, nullptr}, + {X86_INS_VFMADDSUBPD, nullptr}, + {X86_INS_VFMADDSUB213PD, nullptr}, + {X86_INS_VFMADDSUB231PD, nullptr}, + {X86_INS_VFMADDSUBPS, nullptr}, + {X86_INS_VFMADDSUB213PS, nullptr}, + {X86_INS_VFMADDSUB231PS, nullptr}, + {X86_INS_VFMSUB132PD, nullptr}, + {X86_INS_VFMSUB132PS, nullptr}, + {X86_INS_VFMSUBADD132PD, nullptr}, + {X86_INS_VFMSUBADD132PS, nullptr}, + {X86_INS_VFMSUBADDPD, nullptr}, + {X86_INS_VFMSUBADD213PD, nullptr}, + {X86_INS_VFMSUBADD231PD, nullptr}, + {X86_INS_VFMSUBADDPS, nullptr}, + {X86_INS_VFMSUBADD213PS, nullptr}, + {X86_INS_VFMSUBADD231PS, nullptr}, + {X86_INS_VFMSUBPD, nullptr}, + {X86_INS_VFMSUB213PD, nullptr}, + {X86_INS_VFMSUB231PD, nullptr}, + {X86_INS_VFMSUBPS, nullptr}, + {X86_INS_VFMSUB213PS, nullptr}, + {X86_INS_VFMSUB231PS, nullptr}, + {X86_INS_VFMSUBSD, nullptr}, + {X86_INS_VFMSUB213SD, nullptr}, + {X86_INS_VFMSUB132SD, nullptr}, + {X86_INS_VFMSUB231SD, nullptr}, + {X86_INS_VFMSUBSS, nullptr}, + {X86_INS_VFMSUB213SS, nullptr}, + {X86_INS_VFMSUB132SS, nullptr}, + {X86_INS_VFMSUB231SS, nullptr}, + {X86_INS_VFNMADD132PD, nullptr}, + {X86_INS_VFNMADD132PS, nullptr}, + {X86_INS_VFNMADDPD, nullptr}, + {X86_INS_VFNMADD213PD, nullptr}, + {X86_INS_VFNMADD231PD, nullptr}, + {X86_INS_VFNMADDPS, nullptr}, + {X86_INS_VFNMADD213PS, nullptr}, + {X86_INS_VFNMADD231PS, nullptr}, + {X86_INS_VFNMADDSD, nullptr}, + {X86_INS_VFNMADD213SD, nullptr}, + {X86_INS_VFNMADD132SD, nullptr}, + {X86_INS_VFNMADD231SD, nullptr}, + {X86_INS_VFNMADDSS, nullptr}, + {X86_INS_VFNMADD213SS, nullptr}, + {X86_INS_VFNMADD132SS, nullptr}, + {X86_INS_VFNMADD231SS, nullptr}, + {X86_INS_VFNMSUB132PD, nullptr}, + {X86_INS_VFNMSUB132PS, nullptr}, + {X86_INS_VFNMSUBPD, nullptr}, + {X86_INS_VFNMSUB213PD, nullptr}, + {X86_INS_VFNMSUB231PD, nullptr}, + {X86_INS_VFNMSUBPS, nullptr}, + {X86_INS_VFNMSUB213PS, nullptr}, + {X86_INS_VFNMSUB231PS, nullptr}, + {X86_INS_VFNMSUBSD, nullptr}, + {X86_INS_VFNMSUB213SD, nullptr}, + {X86_INS_VFNMSUB132SD, nullptr}, + {X86_INS_VFNMSUB231SD, nullptr}, + {X86_INS_VFNMSUBSS, nullptr}, + {X86_INS_VFNMSUB213SS, nullptr}, + {X86_INS_VFNMSUB132SS, nullptr}, + {X86_INS_VFNMSUB231SS, nullptr}, + {X86_INS_VFRCZPD, nullptr}, + {X86_INS_VFRCZPS, nullptr}, + {X86_INS_VFRCZSD, nullptr}, + {X86_INS_VFRCZSS, nullptr}, + {X86_INS_VORPD, nullptr}, + {X86_INS_VORPS, nullptr}, + {X86_INS_VXORPD, nullptr}, + {X86_INS_VXORPS, nullptr}, + {X86_INS_VGATHERDPD, nullptr}, + {X86_INS_VGATHERDPS, nullptr}, + {X86_INS_VGATHERPF0DPD, nullptr}, + {X86_INS_VGATHERPF0DPS, nullptr}, + {X86_INS_VGATHERPF0QPD, nullptr}, + {X86_INS_VGATHERPF0QPS, nullptr}, + {X86_INS_VGATHERPF1DPD, nullptr}, + {X86_INS_VGATHERPF1DPS, nullptr}, + {X86_INS_VGATHERPF1QPD, nullptr}, + {X86_INS_VGATHERPF1QPS, nullptr}, + {X86_INS_VGATHERQPD, nullptr}, + {X86_INS_VGATHERQPS, nullptr}, + {X86_INS_VHADDPD, nullptr}, + {X86_INS_VHADDPS, nullptr}, + {X86_INS_VHSUBPD, nullptr}, + {X86_INS_VHSUBPS, nullptr}, + {X86_INS_VINSERTF128, nullptr}, + {X86_INS_VINSERTF32X4, nullptr}, + {X86_INS_VINSERTF32X8, nullptr}, + {X86_INS_VINSERTF64X2, nullptr}, + {X86_INS_VINSERTF64X4, nullptr}, + {X86_INS_VINSERTI128, nullptr}, + {X86_INS_VINSERTI32X4, nullptr}, + {X86_INS_VINSERTI32X8, nullptr}, + {X86_INS_VINSERTI64X2, nullptr}, + {X86_INS_VINSERTI64X4, nullptr}, + {X86_INS_VINSERTPS, nullptr}, + {X86_INS_VLDDQU, nullptr}, + {X86_INS_VLDMXCSR, nullptr}, + {X86_INS_VMASKMOVDQU, nullptr}, + {X86_INS_VMASKMOVPD, nullptr}, + {X86_INS_VMASKMOVPS, nullptr}, + {X86_INS_VMAXPD, nullptr}, + {X86_INS_VMAXPS, nullptr}, + {X86_INS_VMAXSD, nullptr}, + {X86_INS_VMAXSS, nullptr}, + {X86_INS_VMCALL, nullptr}, + {X86_INS_VMCLEAR, nullptr}, + {X86_INS_VMFUNC, nullptr}, + {X86_INS_VMINPD, nullptr}, + {X86_INS_VMINPS, nullptr}, + {X86_INS_VMINSD, nullptr}, + {X86_INS_VMINSS, nullptr}, + {X86_INS_VMLAUNCH, nullptr}, + {X86_INS_VMLOAD, nullptr}, + {X86_INS_VMMCALL, nullptr}, + {X86_INS_VMOVQ, nullptr}, + {X86_INS_VMOVDDUP, nullptr}, + {X86_INS_VMOVD, nullptr}, + {X86_INS_VMOVDQA32, nullptr}, + {X86_INS_VMOVDQA64, nullptr}, + {X86_INS_VMOVDQA, nullptr}, + {X86_INS_VMOVDQU16, nullptr}, + {X86_INS_VMOVDQU32, nullptr}, + {X86_INS_VMOVDQU64, nullptr}, + {X86_INS_VMOVDQU8, nullptr}, + {X86_INS_VMOVDQU, nullptr}, + {X86_INS_VMOVHLPS, nullptr}, + {X86_INS_VMOVHPD, nullptr}, + {X86_INS_VMOVHPS, nullptr}, + {X86_INS_VMOVLHPS, nullptr}, + {X86_INS_VMOVLPD, nullptr}, + {X86_INS_VMOVLPS, nullptr}, + {X86_INS_VMOVMSKPD, nullptr}, + {X86_INS_VMOVMSKPS, nullptr}, + {X86_INS_VMOVNTDQA, nullptr}, + {X86_INS_VMOVNTDQ, nullptr}, + {X86_INS_VMOVNTPD, nullptr}, + {X86_INS_VMOVNTPS, nullptr}, + {X86_INS_VMOVSD, nullptr}, + {X86_INS_VMOVSHDUP, nullptr}, + {X86_INS_VMOVSLDUP, nullptr}, + {X86_INS_VMOVSS, nullptr}, + {X86_INS_VMOVUPD, nullptr}, + {X86_INS_VMOVUPS, nullptr}, + {X86_INS_VMPSADBW, nullptr}, + {X86_INS_VMPTRLD, nullptr}, + {X86_INS_VMPTRST, nullptr}, + {X86_INS_VMREAD, nullptr}, + {X86_INS_VMRESUME, nullptr}, + {X86_INS_VMRUN, nullptr}, + {X86_INS_VMSAVE, nullptr}, + {X86_INS_VMULPD, nullptr}, + {X86_INS_VMULPS, nullptr}, + {X86_INS_VMULSD, nullptr}, + {X86_INS_VMULSS, nullptr}, + {X86_INS_VMWRITE, nullptr}, + {X86_INS_VMXOFF, nullptr}, + {X86_INS_VMXON, nullptr}, + {X86_INS_VPABSB, nullptr}, + {X86_INS_VPABSD, nullptr}, + {X86_INS_VPABSQ, nullptr}, + {X86_INS_VPABSW, nullptr}, + {X86_INS_VPACKSSDW, nullptr}, + {X86_INS_VPACKSSWB, nullptr}, + {X86_INS_VPACKUSDW, nullptr}, + {X86_INS_VPACKUSWB, nullptr}, + {X86_INS_VPADDB, nullptr}, + {X86_INS_VPADDD, nullptr}, + {X86_INS_VPADDQ, nullptr}, + {X86_INS_VPADDSB, nullptr}, + {X86_INS_VPADDSW, nullptr}, + {X86_INS_VPADDUSB, nullptr}, + {X86_INS_VPADDUSW, nullptr}, + {X86_INS_VPADDW, nullptr}, + {X86_INS_VPALIGNR, nullptr}, + {X86_INS_VPANDD, nullptr}, + {X86_INS_VPANDND, nullptr}, + {X86_INS_VPANDNQ, nullptr}, + {X86_INS_VPANDN, nullptr}, + {X86_INS_VPANDQ, nullptr}, + {X86_INS_VPAND, nullptr}, + {X86_INS_VPAVGB, nullptr}, + {X86_INS_VPAVGW, nullptr}, + {X86_INS_VPBLENDD, nullptr}, + {X86_INS_VPBLENDMB, nullptr}, + {X86_INS_VPBLENDMD, nullptr}, + {X86_INS_VPBLENDMQ, nullptr}, + {X86_INS_VPBLENDMW, nullptr}, + {X86_INS_VPBLENDVB, nullptr}, + {X86_INS_VPBLENDW, nullptr}, + {X86_INS_VPBROADCASTB, nullptr}, + {X86_INS_VPBROADCASTD, nullptr}, + {X86_INS_VPBROADCASTMB2Q, nullptr}, + {X86_INS_VPBROADCASTMW2D, nullptr}, + {X86_INS_VPBROADCASTQ, nullptr}, + {X86_INS_VPBROADCASTW, nullptr}, + {X86_INS_VPCLMULQDQ, nullptr}, + {X86_INS_VPCMOV, nullptr}, + {X86_INS_VPCMPB, nullptr}, + {X86_INS_VPCMPD, nullptr}, + {X86_INS_VPCMPEQB, nullptr}, + {X86_INS_VPCMPEQD, nullptr}, + {X86_INS_VPCMPEQQ, nullptr}, + {X86_INS_VPCMPEQW, nullptr}, + {X86_INS_VPCMPESTRI, nullptr}, + {X86_INS_VPCMPESTRM, nullptr}, + {X86_INS_VPCMPGTB, nullptr}, + {X86_INS_VPCMPGTD, nullptr}, + {X86_INS_VPCMPGTQ, nullptr}, + {X86_INS_VPCMPGTW, nullptr}, + {X86_INS_VPCMPISTRI, nullptr}, + {X86_INS_VPCMPISTRM, nullptr}, + {X86_INS_VPCMPQ, nullptr}, + {X86_INS_VPCMPUB, nullptr}, + {X86_INS_VPCMPUD, nullptr}, + {X86_INS_VPCMPUQ, nullptr}, + {X86_INS_VPCMPUW, nullptr}, + {X86_INS_VPCMPW, nullptr}, + {X86_INS_VPCOMB, nullptr}, + {X86_INS_VPCOMD, nullptr}, + {X86_INS_VPCOMPRESSD, nullptr}, + {X86_INS_VPCOMPRESSQ, nullptr}, + {X86_INS_VPCOMQ, nullptr}, + {X86_INS_VPCOMUB, nullptr}, + {X86_INS_VPCOMUD, nullptr}, + {X86_INS_VPCOMUQ, nullptr}, + {X86_INS_VPCOMUW, nullptr}, + {X86_INS_VPCOMW, nullptr}, + {X86_INS_VPCONFLICTD, nullptr}, + {X86_INS_VPCONFLICTQ, nullptr}, + {X86_INS_VPERM2F128, nullptr}, + {X86_INS_VPERM2I128, nullptr}, + {X86_INS_VPERMD, nullptr}, + {X86_INS_VPERMI2D, nullptr}, + {X86_INS_VPERMI2PD, nullptr}, + {X86_INS_VPERMI2PS, nullptr}, + {X86_INS_VPERMI2Q, nullptr}, + {X86_INS_VPERMIL2PD, nullptr}, + {X86_INS_VPERMIL2PS, nullptr}, + {X86_INS_VPERMILPD, nullptr}, + {X86_INS_VPERMILPS, nullptr}, + {X86_INS_VPERMPD, nullptr}, + {X86_INS_VPERMPS, nullptr}, + {X86_INS_VPERMQ, nullptr}, + {X86_INS_VPERMT2D, nullptr}, + {X86_INS_VPERMT2PD, nullptr}, + {X86_INS_VPERMT2PS, nullptr}, + {X86_INS_VPERMT2Q, nullptr}, + {X86_INS_VPEXPANDD, nullptr}, + {X86_INS_VPEXPANDQ, nullptr}, + {X86_INS_VPEXTRB, nullptr}, + {X86_INS_VPEXTRD, nullptr}, + {X86_INS_VPEXTRQ, nullptr}, + {X86_INS_VPEXTRW, nullptr}, + {X86_INS_VPGATHERDD, nullptr}, + {X86_INS_VPGATHERDQ, nullptr}, + {X86_INS_VPGATHERQD, nullptr}, + {X86_INS_VPGATHERQQ, nullptr}, + {X86_INS_VPHADDBD, nullptr}, + {X86_INS_VPHADDBQ, nullptr}, + {X86_INS_VPHADDBW, nullptr}, + {X86_INS_VPHADDDQ, nullptr}, + {X86_INS_VPHADDD, nullptr}, + {X86_INS_VPHADDSW, nullptr}, + {X86_INS_VPHADDUBD, nullptr}, + {X86_INS_VPHADDUBQ, nullptr}, + {X86_INS_VPHADDUBW, nullptr}, + {X86_INS_VPHADDUDQ, nullptr}, + {X86_INS_VPHADDUWD, nullptr}, + {X86_INS_VPHADDUWQ, nullptr}, + {X86_INS_VPHADDWD, nullptr}, + {X86_INS_VPHADDWQ, nullptr}, + {X86_INS_VPHADDW, nullptr}, + {X86_INS_VPHMINPOSUW, nullptr}, + {X86_INS_VPHSUBBW, nullptr}, + {X86_INS_VPHSUBDQ, nullptr}, + {X86_INS_VPHSUBD, nullptr}, + {X86_INS_VPHSUBSW, nullptr}, + {X86_INS_VPHSUBWD, nullptr}, + {X86_INS_VPHSUBW, nullptr}, + {X86_INS_VPINSRB, nullptr}, + {X86_INS_VPINSRD, nullptr}, + {X86_INS_VPINSRQ, nullptr}, + {X86_INS_VPINSRW, nullptr}, + {X86_INS_VPLZCNTD, nullptr}, + {X86_INS_VPLZCNTQ, nullptr}, + {X86_INS_VPMACSDD, nullptr}, + {X86_INS_VPMACSDQH, nullptr}, + {X86_INS_VPMACSDQL, nullptr}, + {X86_INS_VPMACSSDD, nullptr}, + {X86_INS_VPMACSSDQH, nullptr}, + {X86_INS_VPMACSSDQL, nullptr}, + {X86_INS_VPMACSSWD, nullptr}, + {X86_INS_VPMACSSWW, nullptr}, + {X86_INS_VPMACSWD, nullptr}, + {X86_INS_VPMACSWW, nullptr}, + {X86_INS_VPMADCSSWD, nullptr}, + {X86_INS_VPMADCSWD, nullptr}, + {X86_INS_VPMADDUBSW, nullptr}, + {X86_INS_VPMADDWD, nullptr}, + {X86_INS_VPMASKMOVD, nullptr}, + {X86_INS_VPMASKMOVQ, nullptr}, + {X86_INS_VPMAXSB, nullptr}, + {X86_INS_VPMAXSD, nullptr}, + {X86_INS_VPMAXSQ, nullptr}, + {X86_INS_VPMAXSW, nullptr}, + {X86_INS_VPMAXUB, nullptr}, + {X86_INS_VPMAXUD, nullptr}, + {X86_INS_VPMAXUQ, nullptr}, + {X86_INS_VPMAXUW, nullptr}, + {X86_INS_VPMINSB, nullptr}, + {X86_INS_VPMINSD, nullptr}, + {X86_INS_VPMINSQ, nullptr}, + {X86_INS_VPMINSW, nullptr}, + {X86_INS_VPMINUB, nullptr}, + {X86_INS_VPMINUD, nullptr}, + {X86_INS_VPMINUQ, nullptr}, + {X86_INS_VPMINUW, nullptr}, + {X86_INS_VPMOVDB, nullptr}, + {X86_INS_VPMOVDW, nullptr}, + {X86_INS_VPMOVM2B, nullptr}, + {X86_INS_VPMOVM2D, nullptr}, + {X86_INS_VPMOVM2Q, nullptr}, + {X86_INS_VPMOVM2W, nullptr}, + {X86_INS_VPMOVMSKB, nullptr}, + {X86_INS_VPMOVQB, nullptr}, + {X86_INS_VPMOVQD, nullptr}, + {X86_INS_VPMOVQW, nullptr}, + {X86_INS_VPMOVSDB, nullptr}, + {X86_INS_VPMOVSDW, nullptr}, + {X86_INS_VPMOVSQB, nullptr}, + {X86_INS_VPMOVSQD, nullptr}, + {X86_INS_VPMOVSQW, nullptr}, + {X86_INS_VPMOVSXBD, nullptr}, + {X86_INS_VPMOVSXBQ, nullptr}, + {X86_INS_VPMOVSXBW, nullptr}, + {X86_INS_VPMOVSXDQ, nullptr}, + {X86_INS_VPMOVSXWD, nullptr}, + {X86_INS_VPMOVSXWQ, nullptr}, + {X86_INS_VPMOVUSDB, nullptr}, + {X86_INS_VPMOVUSDW, nullptr}, + {X86_INS_VPMOVUSQB, nullptr}, + {X86_INS_VPMOVUSQD, nullptr}, + {X86_INS_VPMOVUSQW, nullptr}, + {X86_INS_VPMOVZXBD, nullptr}, + {X86_INS_VPMOVZXBQ, nullptr}, + {X86_INS_VPMOVZXBW, nullptr}, + {X86_INS_VPMOVZXDQ, nullptr}, + {X86_INS_VPMOVZXWD, nullptr}, + {X86_INS_VPMOVZXWQ, nullptr}, + {X86_INS_VPMULDQ, nullptr}, + {X86_INS_VPMULHRSW, nullptr}, + {X86_INS_VPMULHUW, nullptr}, + {X86_INS_VPMULHW, nullptr}, + {X86_INS_VPMULLD, nullptr}, + {X86_INS_VPMULLQ, nullptr}, + {X86_INS_VPMULLW, nullptr}, + {X86_INS_VPMULUDQ, nullptr}, + {X86_INS_VPORD, nullptr}, + {X86_INS_VPORQ, nullptr}, + {X86_INS_VPOR, nullptr}, + {X86_INS_VPPERM, nullptr}, + {X86_INS_VPROTB, nullptr}, + {X86_INS_VPROTD, nullptr}, + {X86_INS_VPROTQ, nullptr}, + {X86_INS_VPROTW, nullptr}, + {X86_INS_VPSADBW, nullptr}, + {X86_INS_VPSCATTERDD, nullptr}, + {X86_INS_VPSCATTERDQ, nullptr}, + {X86_INS_VPSCATTERQD, nullptr}, + {X86_INS_VPSCATTERQQ, nullptr}, + {X86_INS_VPSHAB, nullptr}, + {X86_INS_VPSHAD, nullptr}, + {X86_INS_VPSHAQ, nullptr}, + {X86_INS_VPSHAW, nullptr}, + {X86_INS_VPSHLB, nullptr}, + {X86_INS_VPSHLD, nullptr}, + {X86_INS_VPSHLQ, nullptr}, + {X86_INS_VPSHLW, nullptr}, + {X86_INS_VPSHUFB, nullptr}, + {X86_INS_VPSHUFD, nullptr}, + {X86_INS_VPSHUFHW, nullptr}, + {X86_INS_VPSHUFLW, nullptr}, + {X86_INS_VPSIGNB, nullptr}, + {X86_INS_VPSIGND, nullptr}, + {X86_INS_VPSIGNW, nullptr}, + {X86_INS_VPSLLDQ, nullptr}, + {X86_INS_VPSLLD, nullptr}, + {X86_INS_VPSLLQ, nullptr}, + {X86_INS_VPSLLVD, nullptr}, + {X86_INS_VPSLLVQ, nullptr}, + {X86_INS_VPSLLW, nullptr}, + {X86_INS_VPSRAD, nullptr}, + {X86_INS_VPSRAQ, nullptr}, + {X86_INS_VPSRAVD, nullptr}, + {X86_INS_VPSRAVQ, nullptr}, + {X86_INS_VPSRAW, nullptr}, + {X86_INS_VPSRLDQ, nullptr}, + {X86_INS_VPSRLD, nullptr}, + {X86_INS_VPSRLQ, nullptr}, + {X86_INS_VPSRLVD, nullptr}, + {X86_INS_VPSRLVQ, nullptr}, + {X86_INS_VPSRLW, nullptr}, + {X86_INS_VPSUBB, nullptr}, + {X86_INS_VPSUBD, nullptr}, + {X86_INS_VPSUBQ, nullptr}, + {X86_INS_VPSUBSB, nullptr}, + {X86_INS_VPSUBSW, nullptr}, + {X86_INS_VPSUBUSB, nullptr}, + {X86_INS_VPSUBUSW, nullptr}, + {X86_INS_VPSUBW, nullptr}, + {X86_INS_VPTESTMD, nullptr}, + {X86_INS_VPTESTMQ, nullptr}, + {X86_INS_VPTESTNMD, nullptr}, + {X86_INS_VPTESTNMQ, nullptr}, + {X86_INS_VPTEST, nullptr}, + {X86_INS_VPUNPCKHBW, nullptr}, + {X86_INS_VPUNPCKHDQ, nullptr}, + {X86_INS_VPUNPCKHQDQ, nullptr}, + {X86_INS_VPUNPCKHWD, nullptr}, + {X86_INS_VPUNPCKLBW, nullptr}, + {X86_INS_VPUNPCKLDQ, nullptr}, + {X86_INS_VPUNPCKLQDQ, nullptr}, + {X86_INS_VPUNPCKLWD, nullptr}, + {X86_INS_VPXORD, nullptr}, + {X86_INS_VPXORQ, nullptr}, + {X86_INS_VPXOR, nullptr}, + {X86_INS_VRCP14PD, nullptr}, + {X86_INS_VRCP14PS, nullptr}, + {X86_INS_VRCP14SD, nullptr}, + {X86_INS_VRCP14SS, nullptr}, + {X86_INS_VRCP28PD, nullptr}, + {X86_INS_VRCP28PS, nullptr}, + {X86_INS_VRCP28SD, nullptr}, + {X86_INS_VRCP28SS, nullptr}, + {X86_INS_VRCPPS, nullptr}, + {X86_INS_VRCPSS, nullptr}, + {X86_INS_VRNDSCALEPD, nullptr}, + {X86_INS_VRNDSCALEPS, nullptr}, + {X86_INS_VRNDSCALESD, nullptr}, + {X86_INS_VRNDSCALESS, nullptr}, + {X86_INS_VROUNDPD, nullptr}, + {X86_INS_VROUNDPS, nullptr}, + {X86_INS_VROUNDSD, nullptr}, + {X86_INS_VROUNDSS, nullptr}, + {X86_INS_VRSQRT14PD, nullptr}, + {X86_INS_VRSQRT14PS, nullptr}, + {X86_INS_VRSQRT14SD, nullptr}, + {X86_INS_VRSQRT14SS, nullptr}, + {X86_INS_VRSQRT28PD, nullptr}, + {X86_INS_VRSQRT28PS, nullptr}, + {X86_INS_VRSQRT28SD, nullptr}, + {X86_INS_VRSQRT28SS, nullptr}, + {X86_INS_VRSQRTPS, nullptr}, + {X86_INS_VRSQRTSS, nullptr}, + {X86_INS_VSCATTERDPD, nullptr}, + {X86_INS_VSCATTERDPS, nullptr}, + {X86_INS_VSCATTERPF0DPD, nullptr}, + {X86_INS_VSCATTERPF0DPS, nullptr}, + {X86_INS_VSCATTERPF0QPD, nullptr}, + {X86_INS_VSCATTERPF0QPS, nullptr}, + {X86_INS_VSCATTERPF1DPD, nullptr}, + {X86_INS_VSCATTERPF1DPS, nullptr}, + {X86_INS_VSCATTERPF1QPD, nullptr}, + {X86_INS_VSCATTERPF1QPS, nullptr}, + {X86_INS_VSCATTERQPD, nullptr}, + {X86_INS_VSCATTERQPS, nullptr}, + {X86_INS_VSHUFPD, nullptr}, + {X86_INS_VSHUFPS, nullptr}, + {X86_INS_VSQRTPD, nullptr}, + {X86_INS_VSQRTPS, nullptr}, + {X86_INS_VSQRTSD, nullptr}, + {X86_INS_VSQRTSS, nullptr}, + {X86_INS_VSTMXCSR, nullptr}, + {X86_INS_VSUBPD, nullptr}, + {X86_INS_VSUBPS, nullptr}, + {X86_INS_VSUBSD, nullptr}, + {X86_INS_VSUBSS, nullptr}, + {X86_INS_VTESTPD, nullptr}, + {X86_INS_VTESTPS, nullptr}, + {X86_INS_VUNPCKHPD, nullptr}, + {X86_INS_VUNPCKHPS, nullptr}, + {X86_INS_VUNPCKLPD, nullptr}, + {X86_INS_VUNPCKLPS, nullptr}, + {X86_INS_VZEROALL, nullptr}, + {X86_INS_VZEROUPPER, nullptr}, + {X86_INS_WAIT, nullptr}, + {X86_INS_WBINVD, nullptr}, + {X86_INS_WRFSBASE, nullptr}, + {X86_INS_WRGSBASE, nullptr}, + {X86_INS_WRMSR, nullptr}, + {X86_INS_XABORT, nullptr}, + {X86_INS_XACQUIRE, nullptr}, + {X86_INS_XBEGIN, nullptr}, + {X86_INS_XCHG, &Capstone2LlvmIrTranslatorX86_impl::translateXchg}, + {X86_INS_XCRYPTCBC, nullptr}, + {X86_INS_XCRYPTCFB, nullptr}, + {X86_INS_XCRYPTCTR, nullptr}, + {X86_INS_XCRYPTECB, nullptr}, + {X86_INS_XCRYPTOFB, nullptr}, + {X86_INS_XEND, nullptr}, + {X86_INS_XGETBV, nullptr}, + {X86_INS_XLATB, &Capstone2LlvmIrTranslatorX86_impl::translateXlatb}, + {X86_INS_XRELEASE, nullptr}, + {X86_INS_XRSTOR, nullptr}, + {X86_INS_XRSTOR64, nullptr}, + {X86_INS_XRSTORS, nullptr}, + {X86_INS_XRSTORS64, nullptr}, + {X86_INS_XSAVE, nullptr}, + {X86_INS_XSAVE64, nullptr}, + {X86_INS_XSAVEC, nullptr}, + {X86_INS_XSAVEC64, nullptr}, + {X86_INS_XSAVEOPT, nullptr}, + {X86_INS_XSAVEOPT64, nullptr}, + {X86_INS_XSAVES, nullptr}, + {X86_INS_XSAVES64, nullptr}, + {X86_INS_XSETBV, nullptr}, + {X86_INS_XSHA1, nullptr}, + {X86_INS_XSHA256, nullptr}, + {X86_INS_XSTORE, nullptr}, + {X86_INS_XTEST, nullptr}, + {X86_INS_FDISI8087_NOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_FENI8087_NOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + + // pseudo instructions + {X86_INS_CMPSS, nullptr}, + {X86_INS_CMPSD, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, + {X86_INS_CMPPS, nullptr}, + {X86_INS_CMPPD, nullptr}, + {X86_INS_VCMPSS, nullptr}, + {X86_INS_VCMPSD, nullptr}, + {X86_INS_VCMPPS, nullptr}, + {X86_INS_VCMPPD, nullptr}, + {X86_INS_ENDBR32, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_ENDBR64, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + + {X86_INS_ENDING, nullptr}, // mark the end of the list of insn +}; + +} // namespace capstone2llvmir +} // namespace retdec From 0d50751b79bb55c393e5eceb3829815e4a3d1d6f Mon Sep 17 00:00:00 2001 From: Nitr0-G <120374383+Nitr0-G@users.noreply.github.com> Date: Thu, 27 Apr 2023 21:25:05 +0300 Subject: [PATCH 5/5] Intel MPX support Skipping all MPX instructions has been added in order to eliminate bugs caused on these Issues (#1148 #1135) Proof that these bugs have been fixed, you can find in the same Issue(#1148 #1135) Intel MPX is a dead technology that has not been supported by the Linux kernel since 2020(proof: https://www.phoronix.com/news/Intel-MPX-Is-Dead). It was only in the Skylake and Intel Goldmont(atom) architecture, consider all current processors do not support this technology. Zydis & capstone mistakenly disassembles instructions added to Intel MPX(Intel MPX adds 7 new instructions, as well as BND0-3 registers in x64 and x32 mode for more information, see here(https://intel-mpx.github.io/design/ )), a tool like Hiew also does not disassemble instructions of Intel MPX (https://fpic.in/VQ9yfJ1) Added 6 new instructions(MPX) that translates to NOP --- src/capstone2llvmir/x86/x86_init.cpp | 3914 +++++++++++++------------- 1 file changed, 1957 insertions(+), 1957 deletions(-) diff --git a/src/capstone2llvmir/x86/x86_init.cpp b/src/capstone2llvmir/x86/x86_init.cpp index 0bdefce91..41e04323c 100644 --- a/src/capstone2llvmir/x86/x86_init.cpp +++ b/src/capstone2llvmir/x86/x86_init.cpp @@ -1,1957 +1,1957 @@ -/** - * @file src/capstone2llvmir/x86/x86_init.cpp - * @brief Initializations for X86 implementation of @c Capstone2LlvmIrTranslator. - * @copyright (c) 2017 Avast Software, licensed under the MIT license - */ - -#include "capstone2llvmir/x86/x86_impl.h" - -namespace retdec { -namespace capstone2llvmir { - -// -//============================================================================== -// Pure virtual methods from Capstone2LlvmIrTranslator_impl -//============================================================================== -// - -void Capstone2LlvmIrTranslatorX86_impl::initializeArchSpecific() -{ - initializeRegistersParentMap(); -} - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegNameMap() -{ - std::map r2n = - { - // x86_reg_rflags - // - {X86_REG_CF, "cf"}, - {X86_REG_PF, "pf"}, - {X86_REG_AF, "az"}, - {X86_REG_ZF, "zf"}, - {X86_REG_SF, "sf"}, - {X86_REG_TF, "tf"}, - {X86_REG_IF, "if"}, - {X86_REG_DF, "df"}, - {X86_REG_OF, "of"}, - {X86_REG_IOPL, "iopl"}, - {X86_REG_NT, "nt"}, - {X86_REG_RF, "rf"}, - {X86_REG_VM, "vm"}, - {X86_REG_AC, "ac"}, - {X86_REG_VIF, "vif"}, - {X86_REG_VIP, "vip"}, - {X86_REG_ID, "id"}, - - // x87_reg_status - // - {X87_REG_IE, "fpu_stat_IE"}, - {X87_REG_DE, "fpu_stat_DE"}, - {X87_REG_ZE, "fpu_stat_ZE"}, - {X87_REG_OE, "fpu_stat_OE"}, - {X87_REG_UE, "fpu_stat_UE"}, - {X87_REG_PE, "fpu_stat_PE"}, - {X87_REG_SF, "fpu_stat_SF"}, - {X87_REG_ES, "fpu_stat_ES"}, - {X87_REG_C0, "fpu_stat_C0"}, - {X87_REG_C1, "fpu_stat_C1"}, - {X87_REG_C2, "fpu_stat_C2"}, - {X87_REG_C3, "fpu_stat_C3"}, - {X87_REG_TOP, "fpu_stat_TOP"}, - {X87_REG_B, "fpu_stat_B"}, - - // x87_reg_control - // - {X87_REG_IM, "fpu_control_IM"}, - {X87_REG_DM, "fpu_control_DM"}, - {X87_REG_ZM, "fpu_control_ZM"}, - {X87_REG_OM, "fpu_control_OM"}, - {X87_REG_UM, "fpu_control_UM"}, - {X87_REG_PM, "fpu_control_PM"}, - {X87_REG_PC, "fpu_control_PC"}, - {X87_REG_RC, "fpu_control_RC"}, - {X87_REG_X, "fpu_control_X"}, - - // FPU data registers - // They are named as ST(X) in Capstone, which is not good for us. - // - {X86_REG_ST0, "st0"}, - {X86_REG_ST1, "st1"}, - {X86_REG_ST2, "st2"}, - {X86_REG_ST3, "st3"}, - {X86_REG_ST4, "st4"}, - {X86_REG_ST5, "st5"}, - {X86_REG_ST6, "st6"}, - {X86_REG_ST7, "st7"}, - }; - - _reg2name = std::move(r2n); -} - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegTypeMap() -{ - auto* i1 = llvm::IntegerType::getInt1Ty(_module->getContext()); - auto* i2 = llvm::IntegerType::getIntNTy(_module->getContext(), 2); - auto* i3 = llvm::IntegerType::getIntNTy(_module->getContext(), 3); - auto* i8 = llvm::IntegerType::getInt8Ty(_module->getContext()); - auto* i16 = llvm::IntegerType::getInt16Ty(_module->getContext()); - auto* i32 = llvm::IntegerType::getInt32Ty(_module->getContext()); - auto* i64 = llvm::IntegerType::getInt64Ty(_module->getContext()); - auto* i128 = llvm::IntegerType::getInt128Ty(_module->getContext()); - auto* i256 = llvm::IntegerType::getIntNTy(_module->getContext(), 256); - auto* i512 = llvm::IntegerType::getIntNTy(_module->getContext(), 512); - auto* fp64 = llvm::IntegerType::getDoubleTy(_module->getContext()); - auto* fp80 = llvm::IntegerType::getX86_FP80Ty(_module->getContext()); - - auto* defTy = _origBasicMode == CS_MODE_64 ? i64 : i32; - - std::map r2t = - { - // x86_reg - // - {X86_REG_AH, i8}, - {X86_REG_AL, i8}, - {X86_REG_CH, i8}, - {X86_REG_CL, i8}, - {X86_REG_DH, i8}, - {X86_REG_DL, i8}, - {X86_REG_BH, i8}, - {X86_REG_BL, i8}, - {X86_REG_SPL, i8}, - {X86_REG_BPL, i8}, - {X86_REG_DIL, i8}, - {X86_REG_SIL, i8}, - {X86_REG_R8B, i8}, - {X86_REG_R9B, i8}, - {X86_REG_R10B, i8}, - {X86_REG_R11B, i8}, - {X86_REG_R12B, i8}, - {X86_REG_R13B, i8}, - {X86_REG_R14B, i8}, - {X86_REG_R15B, i8}, - - {X86_REG_AX, i16}, - {X86_REG_CX, i16}, - {X86_REG_DX, i16}, - {X86_REG_BP, i16}, - {X86_REG_BX, i16}, - {X86_REG_DI, i16}, - {X86_REG_SP, i16}, - {X86_REG_SI, i16}, - {X86_REG_SS, i16}, - {X86_REG_CS, i16}, - {X86_REG_DS, i16}, - {X86_REG_ES, i16}, - {X86_REG_FS, i16}, - {X86_REG_GS, i16}, - {X86_REG_R8W, i16}, - {X86_REG_R9W, i16}, - {X86_REG_R10W, i16}, - {X86_REG_R11W, i16}, - {X86_REG_R12W, i16}, - {X86_REG_R13W, i16}, - {X86_REG_R14W, i16}, - {X86_REG_R15W, i16}, - {X86_REG_IP, i16}, - - {X86_REG_EAX, i32}, - {X86_REG_EBP, i32}, - {X86_REG_EBX, i32}, - {X86_REG_ECX, i32}, - {X86_REG_EDI, i32}, - {X86_REG_EDX, i32}, - {X86_REG_ESI, i32}, - {X86_REG_ESP, i32}, - {X86_REG_R8D, i32}, - {X86_REG_R9D, i32}, - {X86_REG_R10D, i32}, - {X86_REG_R11D, i32}, - {X86_REG_R12D, i32}, - {X86_REG_R13D, i32}, - {X86_REG_R14D, i32}, - {X86_REG_R15D, i32}, - {X86_REG_EIP, i32}, - {X86_REG_EIZ, i32}, - - {X86_REG_RAX, i64}, - {X86_REG_RBP, i64}, - {X86_REG_RBX, i64}, - {X86_REG_RCX, i64}, - {X86_REG_RDI, i64}, - {X86_REG_RDX, i64}, - {X86_REG_RIP, i64}, - {X86_REG_RIZ, i64}, - {X86_REG_RSI, i64}, - {X86_REG_RSP, i64}, - {X86_REG_R8, i64}, - {X86_REG_R9, i64}, - {X86_REG_R10, i64}, - {X86_REG_R11, i64}, - {X86_REG_R12, i64}, - {X86_REG_R13, i64}, - {X86_REG_R14, i64}, - {X86_REG_R15, i64}, - - {X86_REG_ST0, fp80}, - {X86_REG_ST1, fp80}, - {X86_REG_ST2, fp80}, - {X86_REG_ST3, fp80}, - {X86_REG_ST4, fp80}, - {X86_REG_ST5, fp80}, - {X86_REG_ST6, fp80}, - {X86_REG_ST7, fp80}, - - {X86_REG_FP0, fp64}, - {X86_REG_FP1, fp64}, - {X86_REG_FP2, fp64}, - {X86_REG_FP3, fp64}, - {X86_REG_FP4, fp64}, - {X86_REG_FP5, fp64}, - {X86_REG_FP6, fp64}, - {X86_REG_FP7, fp64}, - - {X86_REG_EFLAGS, defTy}, - {X86_REG_DR0, defTy}, - {X86_REG_DR1, defTy}, - {X86_REG_DR2, defTy}, - {X86_REG_DR3, defTy}, - {X86_REG_DR4, defTy}, - {X86_REG_DR5, defTy}, - {X86_REG_DR6, defTy}, - {X86_REG_DR7, defTy}, - {X86_REG_DR8, defTy}, - {X86_REG_DR9, defTy}, - {X86_REG_DR10, defTy}, - {X86_REG_DR11, defTy}, - {X86_REG_DR12, defTy}, - {X86_REG_DR13, defTy}, - {X86_REG_DR14, defTy}, - {X86_REG_DR15, defTy}, - - {X86_REG_CR0, defTy}, - {X86_REG_CR1, defTy}, - {X86_REG_CR2, defTy}, - {X86_REG_CR3, defTy}, - {X86_REG_CR4, defTy}, - {X86_REG_CR5, defTy}, - {X86_REG_CR6, defTy}, - {X86_REG_CR7, defTy}, - {X86_REG_CR8, defTy}, - {X86_REG_CR9, defTy}, - {X86_REG_CR10, defTy}, - {X86_REG_CR11, defTy}, - {X86_REG_CR12, defTy}, - {X86_REG_CR13, defTy}, - {X86_REG_CR14, defTy}, - {X86_REG_CR15, defTy}, - - {X86_REG_FPSW, defTy}, - - // opmask registers (AVX-512) - {X86_REG_K0, i64}, - {X86_REG_K1, i64}, - {X86_REG_K2, i64}, - {X86_REG_K3, i64}, - {X86_REG_K4, i64}, - {X86_REG_K5, i64}, - {X86_REG_K6, i64}, - {X86_REG_K7, i64}, - - // MMX - {X86_REG_MM0, i64}, - {X86_REG_MM1, i64}, - {X86_REG_MM2, i64}, - {X86_REG_MM3, i64}, - {X86_REG_MM4, i64}, - {X86_REG_MM5, i64}, - {X86_REG_MM6, i64}, - {X86_REG_MM7, i64}, - - // XMM - {X86_REG_XMM0, i128}, - {X86_REG_XMM1, i128}, - {X86_REG_XMM2, i128}, - {X86_REG_XMM3, i128}, - {X86_REG_XMM4, i128}, - {X86_REG_XMM5, i128}, - {X86_REG_XMM6, i128}, - {X86_REG_XMM7, i128}, - {X86_REG_XMM8, i128}, - {X86_REG_XMM9, i128}, - {X86_REG_XMM10, i128}, - {X86_REG_XMM11, i128}, - {X86_REG_XMM12, i128}, - {X86_REG_XMM13, i128}, - {X86_REG_XMM14, i128}, - {X86_REG_XMM15, i128}, - {X86_REG_XMM16, i128}, - {X86_REG_XMM17, i128}, - {X86_REG_XMM18, i128}, - {X86_REG_XMM19, i128}, - {X86_REG_XMM20, i128}, - {X86_REG_XMM21, i128}, - {X86_REG_XMM22, i128}, - {X86_REG_XMM23, i128}, - {X86_REG_XMM24, i128}, - {X86_REG_XMM25, i128}, - {X86_REG_XMM26, i128}, - {X86_REG_XMM27, i128}, - {X86_REG_XMM28, i128}, - {X86_REG_XMM29, i128}, - {X86_REG_XMM30, i128}, - {X86_REG_XMM31, i128}, - - // YMM - {X86_REG_YMM0, i256}, - {X86_REG_YMM1, i256}, - {X86_REG_YMM2, i256}, - {X86_REG_YMM3, i256}, - {X86_REG_YMM4, i256}, - {X86_REG_YMM5, i256}, - {X86_REG_YMM6, i256}, - {X86_REG_YMM7, i256}, - {X86_REG_YMM8, i256}, - {X86_REG_YMM9, i256}, - {X86_REG_YMM10, i256}, - {X86_REG_YMM11, i256}, - {X86_REG_YMM12, i256}, - {X86_REG_YMM13, i256}, - {X86_REG_YMM14, i256}, - {X86_REG_YMM15, i256}, - {X86_REG_YMM16, i256}, - {X86_REG_YMM17, i256}, - {X86_REG_YMM18, i256}, - {X86_REG_YMM19, i256}, - {X86_REG_YMM20, i256}, - {X86_REG_YMM21, i256}, - {X86_REG_YMM22, i256}, - {X86_REG_YMM23, i256}, - {X86_REG_YMM24, i256}, - {X86_REG_YMM25, i256}, - {X86_REG_YMM26, i256}, - {X86_REG_YMM27, i256}, - {X86_REG_YMM28, i256}, - {X86_REG_YMM29, i256}, - {X86_REG_YMM30, i256}, - {X86_REG_YMM31, i256}, - - // ZMM - {X86_REG_ZMM0, i512}, - {X86_REG_ZMM1, i512}, - {X86_REG_ZMM2, i512}, - {X86_REG_ZMM3, i512}, - {X86_REG_ZMM4, i512}, - {X86_REG_ZMM5, i512}, - {X86_REG_ZMM6, i512}, - {X86_REG_ZMM7, i512}, - {X86_REG_ZMM8, i512}, - {X86_REG_ZMM9, i512}, - {X86_REG_ZMM10, i512}, - {X86_REG_ZMM11, i512}, - {X86_REG_ZMM12, i512}, - {X86_REG_ZMM13, i512}, - {X86_REG_ZMM14, i512}, - {X86_REG_ZMM15, i512}, - {X86_REG_ZMM16, i512}, - {X86_REG_ZMM17, i512}, - {X86_REG_ZMM18, i512}, - {X86_REG_ZMM19, i512}, - {X86_REG_ZMM20, i512}, - {X86_REG_ZMM21, i512}, - {X86_REG_ZMM22, i512}, - {X86_REG_ZMM23, i512}, - {X86_REG_ZMM24, i512}, - {X86_REG_ZMM25, i512}, - {X86_REG_ZMM26, i512}, - {X86_REG_ZMM27, i512}, - {X86_REG_ZMM28, i512}, - {X86_REG_ZMM29, i512}, - {X86_REG_ZMM30, i512}, - {X86_REG_ZMM31, i512}, - - // x86_reg_rflags - // - {X86_REG_CF, i1}, - {X86_REG_PF, i1}, - {X86_REG_AF, i1}, - {X86_REG_ZF, i1}, - {X86_REG_SF, i1}, - {X86_REG_TF, i1}, - {X86_REG_IF, i1}, - {X86_REG_DF, i1}, - {X86_REG_OF, i1}, - {X86_REG_IOPL, i2}, - {X86_REG_NT, i1}, - {X86_REG_RF, i1}, - {X86_REG_VM, i1}, - {X86_REG_AC, i1}, - {X86_REG_VIF, i1}, - {X86_REG_VIP, i1}, - {X86_REG_ID, i1}, - - // x87_reg_status - // - {X87_REG_IE, i1}, - {X87_REG_DE, i1}, - {X87_REG_ZE, i1}, - {X87_REG_OE, i1}, - {X87_REG_UE, i1}, - {X87_REG_PE, i1}, - {X87_REG_SF, i1}, - {X87_REG_ES, i1}, - {X87_REG_C0, i1}, - {X87_REG_C1, i1}, - {X87_REG_C2, i1}, - {X87_REG_C3, i1}, - {X87_REG_TOP, i3}, - {X87_REG_B, i1}, - - // x87_reg_control - // - {X87_REG_IM, i1}, - {X87_REG_DM, i1}, - {X87_REG_ZM, i1}, - {X87_REG_OM, i1}, - {X87_REG_UM, i1}, - {X87_REG_PM, i1}, - {X87_REG_PC, i2}, - {X87_REG_RC, i2}, - {X87_REG_X, i1}, - }; - - _reg2type = std::move(r2t); -} - -void Capstone2LlvmIrTranslatorX86_impl::initializePseudoCallInstructionIDs() -{ - _callInsnIds = - { - X86_INS_CALL, - X86_INS_LCALL, - }; - - _returnInsnIds = - { - X86_INS_RET, - X86_INS_RETF, - X86_INS_RETFQ - }; - - _branchInsnIds = - { - X86_INS_JMP, - X86_INS_LJMP, - }; - - _condBranchInsnIds = - { - X86_INS_JCXZ, - X86_INS_JECXZ, - X86_INS_JRCXZ, - // - X86_INS_LOOP, - X86_INS_LOOPE, - X86_INS_LOOPNE, - // - X86_INS_JAE, - X86_INS_JA, - X86_INS_JBE, - X86_INS_JB, - X86_INS_JE, - X86_INS_JGE, - X86_INS_JG, - X86_INS_JLE, - X86_INS_JL, - X86_INS_JNE, - X86_INS_JNO, - X86_INS_JNP, - X86_INS_JNS, - X86_INS_JO, - X86_INS_JP, - X86_INS_JS, - }; - - _controlFlowInsnIds = - { - // Currently, all instructions can be categorized based on their - // IDs alone. - }; -} - -// -//============================================================================== -// x86-specific methods. -//============================================================================== -// - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMapToOther( - const std::vector& rs, - x86_reg other) -{ - for (auto r : rs) - { - if (r >= _reg2parentMap.size()) - { - throw GenericError("Register out of range."); - } - _reg2parentMap[r] = other; - } -} - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap() -{ - switch (_origBasicMode) - { - case CS_MODE_16: initializeRegistersParentMap16(); break; - case CS_MODE_32: initializeRegistersParentMap32(); break; - case CS_MODE_64: initializeRegistersParentMap64(); break; - default: - { - throw GenericError("Unhandled mode in " - "initializeRegistersParentMap()."); - break; - } - } -} - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap16() -{ - // Last element in vector is its own parent. - std::vector> rss = - { - {X86_REG_AH, X86_REG_AL, X86_REG_AX}, - {X86_REG_CH, X86_REG_CL, X86_REG_CX}, - {X86_REG_DH, X86_REG_DL, X86_REG_DX}, - {X86_REG_BH, X86_REG_BL, X86_REG_BX}, - {X86_REG_SPL, X86_REG_SP}, - {X86_REG_BPL, X86_REG_BP}, - {X86_REG_SIL, X86_REG_SI}, - {X86_REG_DIL, X86_REG_DI}, - {X86_REG_IP}, - }; - - for (std::vector& rs : rss) - { - initializeRegistersParentMapToOther(rs, rs.back()); - } -} - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap32() -{ - // Last element in vector is its own parent. - std::vector> rss = - { - {X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_EAX}, - {X86_REG_CH, X86_REG_CL, X86_REG_CX, X86_REG_ECX}, - {X86_REG_DH, X86_REG_DL, X86_REG_DX, X86_REG_EDX}, - {X86_REG_BH, X86_REG_BL, X86_REG_BX, X86_REG_EBX}, - {X86_REG_SPL, X86_REG_SP, X86_REG_ESP}, - {X86_REG_BPL, X86_REG_BP, X86_REG_EBP}, - {X86_REG_SIL, X86_REG_SI, X86_REG_ESI}, - {X86_REG_DIL, X86_REG_DI, X86_REG_EDI}, - {X86_REG_IP, X86_REG_EIP}, - {X86_REG_EIZ}, - }; - - for (std::vector& rs : rss) - { - initializeRegistersParentMapToOther(rs, rs.back()); - } -} - -void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap64() -{ - // Last element in vector is its own parent. - std::vector> rss = - { - {X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_EAX, X86_REG_RAX}, - {X86_REG_CH, X86_REG_CL, X86_REG_CX, X86_REG_ECX, X86_REG_RCX}, - {X86_REG_DH, X86_REG_DL, X86_REG_DX, X86_REG_EDX, X86_REG_RDX}, - {X86_REG_BH, X86_REG_BL, X86_REG_BX, X86_REG_EBX, X86_REG_RBX}, - {X86_REG_SPL, X86_REG_SP, X86_REG_ESP, X86_REG_RSP}, - {X86_REG_BPL, X86_REG_BP, X86_REG_EBP, X86_REG_RBP}, - {X86_REG_SIL, X86_REG_SI, X86_REG_ESI, X86_REG_RSI}, - {X86_REG_DIL, X86_REG_DI, X86_REG_EDI, X86_REG_RDI}, - {X86_REG_IP, X86_REG_EIP, X86_REG_RIP}, - {X86_REG_EIZ, X86_REG_RIZ}, - {X86_REG_R8B, X86_REG_R8W, X86_REG_R8D, X86_REG_R8}, - {X86_REG_R9B, X86_REG_R9W, X86_REG_R9D, X86_REG_R9}, - {X86_REG_R10B, X86_REG_R10W, X86_REG_R10D, X86_REG_R10}, - {X86_REG_R11B, X86_REG_R11W, X86_REG_R11D, X86_REG_R11}, - {X86_REG_R12B, X86_REG_R12W, X86_REG_R12D, X86_REG_R12}, - {X86_REG_R13B, X86_REG_R13W, X86_REG_R13D, X86_REG_R13}, - {X86_REG_R14B, X86_REG_R14W, X86_REG_R14D, X86_REG_R14}, - {X86_REG_R15B, X86_REG_R15W, X86_REG_R15D, X86_REG_R15} - }; - - for (std::vector& rs : rss) - { - initializeRegistersParentMapToOther(rs, rs.back()); - } -} - -// -//============================================================================== -// Instruction translation map initialization. -//============================================================================== -// - -std::map< - std::size_t, - void (Capstone2LlvmIrTranslatorX86_impl::*)( - cs_insn* i, - cs_x86*, - llvm::IRBuilder<>&)> -Capstone2LlvmIrTranslatorX86_impl::_i2fm = -{ - {X86_INS_INVALID, nullptr}, - - {X86_INS_AAA, &Capstone2LlvmIrTranslatorX86_impl::translateAaa}, - {X86_INS_AAD, &Capstone2LlvmIrTranslatorX86_impl::translateAad}, - {X86_INS_AAM, &Capstone2LlvmIrTranslatorX86_impl::translateAam}, - {X86_INS_AAS, &Capstone2LlvmIrTranslatorX86_impl::translateAaa}, - {X86_INS_FABS, &Capstone2LlvmIrTranslatorX86_impl::translateFabs}, - {X86_INS_ADC, &Capstone2LlvmIrTranslatorX86_impl::translateAdc}, - {X86_INS_ADCX, &Capstone2LlvmIrTranslatorX86_impl::translateAdc}, - {X86_INS_ADD, &Capstone2LlvmIrTranslatorX86_impl::translateAdd}, - {X86_INS_ADDPD, nullptr}, - {X86_INS_ADDPS, nullptr}, - {X86_INS_ADDSD, nullptr}, - {X86_INS_ADDSS, nullptr}, - {X86_INS_ADDSUBPD, nullptr}, - {X86_INS_ADDSUBPS, nullptr}, - {X86_INS_FADD, &Capstone2LlvmIrTranslatorX86_impl::translateFadd}, - {X86_INS_FIADD, &Capstone2LlvmIrTranslatorX86_impl::translateFadd}, - {X86_INS_ADOX, &Capstone2LlvmIrTranslatorX86_impl::translateAdc}, - {X86_INS_AESDECLAST, nullptr}, - {X86_INS_AESDEC, nullptr}, - {X86_INS_AESENCLAST, nullptr}, - {X86_INS_AESENC, nullptr}, - {X86_INS_AESIMC, nullptr}, - {X86_INS_AESKEYGENASSIST, nullptr}, - {X86_INS_AND, &Capstone2LlvmIrTranslatorX86_impl::translateAnd}, - {X86_INS_ANDN, nullptr}, - {X86_INS_ANDNPD, nullptr}, - {X86_INS_ANDNPS, nullptr}, - {X86_INS_ANDPD, nullptr}, - {X86_INS_ANDPS, nullptr}, - {X86_INS_ARPL, nullptr}, - {X86_INS_BEXTR, nullptr}, - {X86_INS_BLCFILL, nullptr}, - {X86_INS_BLCI, nullptr}, - {X86_INS_BLCIC, nullptr}, - {X86_INS_BLCMSK, nullptr}, - {X86_INS_BLCS, nullptr}, - {X86_INS_BLENDPD, nullptr}, - {X86_INS_BLENDPS, nullptr}, - {X86_INS_BLENDVPD, nullptr}, - {X86_INS_BLENDVPS, nullptr}, - {X86_INS_BLSFILL, nullptr}, - {X86_INS_BLSI, nullptr}, - {X86_INS_BLSIC, nullptr}, - {X86_INS_BLSMSK, nullptr}, - {X86_INS_BLSR, nullptr}, - {X86_INS_BOUND, nullptr}, - {X86_INS_BSF, &Capstone2LlvmIrTranslatorX86_impl::translateBsf}, - {X86_INS_BSR, &Capstone2LlvmIrTranslatorX86_impl::translateBsf}, - {X86_INS_BSWAP, &Capstone2LlvmIrTranslatorX86_impl::translateBswap}, - {X86_INS_BT, &Capstone2LlvmIrTranslatorX86_impl::translateBt}, - {X86_INS_BTC, &Capstone2LlvmIrTranslatorX86_impl::translateBtc}, - {X86_INS_BTR, &Capstone2LlvmIrTranslatorX86_impl::translateBtr}, - {X86_INS_BTS, &Capstone2LlvmIrTranslatorX86_impl::translateBts}, - {X86_INS_BZHI, nullptr}, - {X86_INS_BNDMK, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_BNDCL, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_BNDCU, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_BNDMOV, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_BNDLDX, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_BNDSTX, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_CALL, &Capstone2LlvmIrTranslatorX86_impl::translateCall}, - {X86_INS_CBW, &Capstone2LlvmIrTranslatorX86_impl::translateCbw}, - {X86_INS_CDQ, &Capstone2LlvmIrTranslatorX86_impl::translateCdq}, - {X86_INS_CDQE, &Capstone2LlvmIrTranslatorX86_impl::translateCdqe}, - {X86_INS_FCHS, &Capstone2LlvmIrTranslatorX86_impl::translateFchs}, - {X86_INS_CLAC, nullptr}, - {X86_INS_CLC, &Capstone2LlvmIrTranslatorX86_impl::translateClc}, - {X86_INS_CLD, &Capstone2LlvmIrTranslatorX86_impl::translateCld}, - {X86_INS_CLFLUSH, nullptr}, - {X86_INS_CLFLUSHOPT, nullptr}, - {X86_INS_CLGI, nullptr}, - {X86_INS_CLI, &Capstone2LlvmIrTranslatorX86_impl::translateCli}, - {X86_INS_CLTS, nullptr}, - {X86_INS_CLWB, nullptr}, - {X86_INS_CMC, &Capstone2LlvmIrTranslatorX86_impl::translateCmc}, - {X86_INS_CMOVA, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVAE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVB, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVBE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_FCMOVBE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_FCMOVB, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_CMOVE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_FCMOVE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_CMOVG, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVGE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVL, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVLE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_FCMOVNBE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_FCMOVNB, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_CMOVNE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_FCMOVNE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_CMOVNO, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVNP, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_FCMOVNU, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_CMOVNS, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVO, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMOVP, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_FCMOVU, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, - {X86_INS_CMOVS, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, - {X86_INS_CMP, &Capstone2LlvmIrTranslatorX86_impl::translateSub}, - {X86_INS_CMPSB, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, - {X86_INS_CMPSQ, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, - {X86_INS_CMPSW, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, - {X86_INS_CMPXCHG16B, &Capstone2LlvmIrTranslatorX86_impl::translateCmpxchg16b}, - {X86_INS_CMPXCHG, &Capstone2LlvmIrTranslatorX86_impl::translateCmpxchg}, - {X86_INS_CMPXCHG8B, &Capstone2LlvmIrTranslatorX86_impl::translateCmpxchg8b}, - {X86_INS_COMISD, nullptr}, - {X86_INS_COMISS, nullptr}, - {X86_INS_FCOMP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FCOMPI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FCOMI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FCOM, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FCOS, &Capstone2LlvmIrTranslatorX86_impl::translateFcos}, - {X86_INS_CPUID, &Capstone2LlvmIrTranslatorX86_impl::translateCpuid}, - {X86_INS_CQO, &Capstone2LlvmIrTranslatorX86_impl::translateCqo}, - {X86_INS_CRC32, nullptr}, - {X86_INS_CVTDQ2PD, nullptr}, - {X86_INS_CVTDQ2PS, nullptr}, - {X86_INS_CVTPD2DQ, nullptr}, - {X86_INS_CVTPD2PS, nullptr}, - {X86_INS_CVTPS2DQ, nullptr}, - {X86_INS_CVTPS2PD, nullptr}, - {X86_INS_CVTSD2SI, nullptr}, - {X86_INS_CVTSD2SS, nullptr}, - {X86_INS_CVTSI2SD, nullptr}, - {X86_INS_CVTSI2SS, nullptr}, - {X86_INS_CVTSS2SD, nullptr}, - {X86_INS_CVTSS2SI, nullptr}, - {X86_INS_CVTTPD2DQ, nullptr}, - {X86_INS_CVTTPS2DQ, nullptr}, - {X86_INS_CVTTSD2SI, nullptr}, - {X86_INS_CVTTSS2SI, nullptr}, - {X86_INS_CWD, &Capstone2LlvmIrTranslatorX86_impl::translateCwd}, - {X86_INS_CWDE, &Capstone2LlvmIrTranslatorX86_impl::translateCwde}, - {X86_INS_DAA, &Capstone2LlvmIrTranslatorX86_impl::translateDaaDas}, - {X86_INS_DAS, &Capstone2LlvmIrTranslatorX86_impl::translateDaaDas}, - {X86_INS_DATA16, nullptr}, - {X86_INS_DEC, &Capstone2LlvmIrTranslatorX86_impl::translateDec}, - {X86_INS_DIV, &Capstone2LlvmIrTranslatorX86_impl::translateDiv}, - {X86_INS_DIVPD, nullptr}, - {X86_INS_DIVPS, nullptr}, - {X86_INS_FDIVR, &Capstone2LlvmIrTranslatorX86_impl::translateFdivr}, - {X86_INS_FIDIVR, &Capstone2LlvmIrTranslatorX86_impl::translateFdivr}, - {X86_INS_FDIVRP, &Capstone2LlvmIrTranslatorX86_impl::translateFdivr}, - {X86_INS_DIVSD, nullptr}, - {X86_INS_DIVSS, nullptr}, - {X86_INS_FDIV, &Capstone2LlvmIrTranslatorX86_impl::translateFdiv}, - {X86_INS_FIDIV, &Capstone2LlvmIrTranslatorX86_impl::translateFdiv}, - {X86_INS_FDIVP, &Capstone2LlvmIrTranslatorX86_impl::translateFdiv}, - {X86_INS_DPPD, nullptr}, - {X86_INS_DPPS, nullptr}, - {X86_INS_RET, &Capstone2LlvmIrTranslatorX86_impl::translateRet}, - {X86_INS_ENCLS, nullptr}, - {X86_INS_ENCLU, nullptr}, - {X86_INS_ENTER, &Capstone2LlvmIrTranslatorX86_impl::translateEnter}, - {X86_INS_EXTRACTPS, nullptr}, - {X86_INS_EXTRQ, nullptr}, - {X86_INS_F2XM1, &Capstone2LlvmIrTranslatorX86_impl::translateF2xm1}, - {X86_INS_LCALL, &Capstone2LlvmIrTranslatorX86_impl::translateLcall}, - {X86_INS_LJMP, &Capstone2LlvmIrTranslatorX86_impl::translateLjmp}, - {X86_INS_FBLD, &Capstone2LlvmIrTranslatorX86_impl::translateFbld}, - {X86_INS_FBSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFbstp}, - {X86_INS_FCOMPP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FDECSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFdecstp}, - {X86_INS_FEMMS, nullptr}, - {X86_INS_FFREE, &Capstone2LlvmIrTranslatorX86_impl::translateFfree}, - {X86_INS_FICOM, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FICOMP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FINCSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFincstp}, - {X86_INS_FLDCW, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_FLDENV, &Capstone2LlvmIrTranslatorX86_impl::translatePseudoAsmFncOp0}, - {X86_INS_FLDL2E, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FLDL2T, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FLDLG2, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FLDLN2, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FLDPI, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FNCLEX, &Capstone2LlvmIrTranslatorX86_impl::translateFnclex}, - {X86_INS_FNINIT, &Capstone2LlvmIrTranslatorX86_impl::translateFninit}, - {X86_INS_FNOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_FNSTCW, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_FNSTSW, &Capstone2LlvmIrTranslatorX86_impl::translateFnstsw}, - {X86_INS_FPATAN, &Capstone2LlvmIrTranslatorX86_impl::translateFatan}, - {X86_INS_FPREM, &Capstone2LlvmIrTranslatorX86_impl::translateFprem}, - {X86_INS_FPREM1, &Capstone2LlvmIrTranslatorX86_impl::translateFprem}, - {X86_INS_FPTAN, &Capstone2LlvmIrTranslatorX86_impl::translateFtan}, - {X86_INS_FFREEP, nullptr}, - {X86_INS_FRNDINT, &Capstone2LlvmIrTranslatorX86_impl::translateFrndint}, - {X86_INS_FRSTOR, &Capstone2LlvmIrTranslatorX86_impl::translateFrstor}, - {X86_INS_FNSAVE, &Capstone2LlvmIrTranslatorX86_impl::translateFnsave}, - {X86_INS_FSCALE, &Capstone2LlvmIrTranslatorX86_impl::translateFscale}, - {X86_INS_FSETPM, nullptr}, - {X86_INS_FSINCOS, &Capstone2LlvmIrTranslatorX86_impl::translateFsincos}, - {X86_INS_FNSTENV, &Capstone2LlvmIrTranslatorX86_impl::translateFnstenv}, - {X86_INS_FXAM, &Capstone2LlvmIrTranslatorX86_impl::translateFxam}, - {X86_INS_FXRSTOR, &Capstone2LlvmIrTranslatorX86_impl::translateFxstor}, - {X86_INS_FXRSTOR64, &Capstone2LlvmIrTranslatorX86_impl::translateFxstor}, - {X86_INS_FXSAVE, &Capstone2LlvmIrTranslatorX86_impl::translateFxsave}, - {X86_INS_FXSAVE64, &Capstone2LlvmIrTranslatorX86_impl::translateFxsave}, - {X86_INS_FXTRACT, &Capstone2LlvmIrTranslatorX86_impl::translateFxtract}, - {X86_INS_FYL2X, &Capstone2LlvmIrTranslatorX86_impl::translateFyl2x}, - {X86_INS_FYL2XP1, &Capstone2LlvmIrTranslatorX86_impl::translateFyl2x}, - {X86_INS_MOVAPD, nullptr}, - {X86_INS_MOVAPS, nullptr}, - {X86_INS_ORPD, nullptr}, - {X86_INS_ORPS, nullptr}, - {X86_INS_VMOVAPD, nullptr}, - {X86_INS_VMOVAPS, nullptr}, - {X86_INS_XORPD, nullptr}, - {X86_INS_XORPS, nullptr}, - {X86_INS_GETSEC, nullptr}, - {X86_INS_HADDPD, nullptr}, - {X86_INS_HADDPS, nullptr}, - {X86_INS_HLT, nullptr}, - {X86_INS_HSUBPD, nullptr}, - {X86_INS_HSUBPS, nullptr}, - {X86_INS_IDIV, &Capstone2LlvmIrTranslatorX86_impl::translateDiv}, - {X86_INS_FILD, &Capstone2LlvmIrTranslatorX86_impl::translateFld}, - {X86_INS_IMUL, &Capstone2LlvmIrTranslatorX86_impl::translateImul}, - {X86_INS_IN, nullptr}, - {X86_INS_INC, &Capstone2LlvmIrTranslatorX86_impl::translateInc}, - {X86_INS_INSB, &Capstone2LlvmIrTranslatorX86_impl::translateIns}, - {X86_INS_INSERTPS, nullptr}, - {X86_INS_INSERTQ, nullptr}, - {X86_INS_INSD, &Capstone2LlvmIrTranslatorX86_impl::translateIns}, - {X86_INS_INSW, &Capstone2LlvmIrTranslatorX86_impl::translateIns}, - {X86_INS_INT, nullptr}, - {X86_INS_INT1, nullptr}, - {X86_INS_INT3, nullptr}, - {X86_INS_INTO, nullptr}, - {X86_INS_INVD, nullptr}, - {X86_INS_INVEPT, nullptr}, - {X86_INS_INVLPG, nullptr}, - {X86_INS_INVLPGA, nullptr}, - {X86_INS_INVPCID, nullptr}, - {X86_INS_INVVPID, nullptr}, - {X86_INS_IRET, nullptr}, - {X86_INS_IRETD, nullptr}, - {X86_INS_IRETQ, nullptr}, - {X86_INS_FISTTP, &Capstone2LlvmIrTranslatorX86_impl::translateFist}, - {X86_INS_FIST, &Capstone2LlvmIrTranslatorX86_impl::translateFist}, - {X86_INS_FISTP, &Capstone2LlvmIrTranslatorX86_impl::translateFist}, - {X86_INS_UCOMISD, nullptr}, - {X86_INS_UCOMISS, nullptr}, - {X86_INS_VCOMISD, nullptr}, - {X86_INS_VCOMISS, nullptr}, - {X86_INS_VCVTSD2SS, nullptr}, - {X86_INS_VCVTSI2SD, nullptr}, - {X86_INS_VCVTSI2SS, nullptr}, - {X86_INS_VCVTSS2SD, nullptr}, - {X86_INS_VCVTTSD2SI, nullptr}, - {X86_INS_VCVTTSD2USI, nullptr}, - {X86_INS_VCVTTSS2SI, nullptr}, - {X86_INS_VCVTTSS2USI, nullptr}, - {X86_INS_VCVTUSI2SD, nullptr}, - {X86_INS_VCVTUSI2SS, nullptr}, - {X86_INS_VUCOMISD, nullptr}, - {X86_INS_VUCOMISS, nullptr}, - {X86_INS_JAE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JA, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JBE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JB, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JCXZ, &Capstone2LlvmIrTranslatorX86_impl::translateJecxz}, - {X86_INS_JECXZ, &Capstone2LlvmIrTranslatorX86_impl::translateJecxz}, - {X86_INS_JE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JGE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JG, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JLE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JL, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JMP, &Capstone2LlvmIrTranslatorX86_impl::translateJmp}, - {X86_INS_JNE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JNO, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JNP, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JNS, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JO, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JP, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_JRCXZ, &Capstone2LlvmIrTranslatorX86_impl::translateJecxz}, - {X86_INS_JS, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, - {X86_INS_KANDB, nullptr}, - {X86_INS_KANDD, nullptr}, - {X86_INS_KANDNB, nullptr}, - {X86_INS_KANDND, nullptr}, - {X86_INS_KANDNQ, nullptr}, - {X86_INS_KANDNW, nullptr}, - {X86_INS_KANDQ, nullptr}, - {X86_INS_KANDW, nullptr}, - {X86_INS_KMOVB, nullptr}, - {X86_INS_KMOVD, nullptr}, - {X86_INS_KMOVQ, nullptr}, - {X86_INS_KMOVW, nullptr}, - {X86_INS_KNOTB, nullptr}, - {X86_INS_KNOTD, nullptr}, - {X86_INS_KNOTQ, nullptr}, - {X86_INS_KNOTW, nullptr}, - {X86_INS_KORB, nullptr}, - {X86_INS_KORD, nullptr}, - {X86_INS_KORQ, nullptr}, - {X86_INS_KORTESTB, nullptr}, - {X86_INS_KORTESTD, nullptr}, - {X86_INS_KORTESTQ, nullptr}, - {X86_INS_KORTESTW, nullptr}, - {X86_INS_KORW, nullptr}, - {X86_INS_KSHIFTLB, nullptr}, - {X86_INS_KSHIFTLD, nullptr}, - {X86_INS_KSHIFTLQ, nullptr}, - {X86_INS_KSHIFTLW, nullptr}, - {X86_INS_KSHIFTRB, nullptr}, - {X86_INS_KSHIFTRD, nullptr}, - {X86_INS_KSHIFTRQ, nullptr}, - {X86_INS_KSHIFTRW, nullptr}, - {X86_INS_KUNPCKBW, nullptr}, - {X86_INS_KXNORB, nullptr}, - {X86_INS_KXNORD, nullptr}, - {X86_INS_KXNORQ, nullptr}, - {X86_INS_KXNORW, nullptr}, - {X86_INS_KXORB, nullptr}, - {X86_INS_KXORD, nullptr}, - {X86_INS_KXORQ, nullptr}, - {X86_INS_KXORW, nullptr}, - {X86_INS_LAHF, &Capstone2LlvmIrTranslatorX86_impl::translateLahf}, - {X86_INS_LAR, nullptr}, - {X86_INS_LDDQU, nullptr}, - {X86_INS_LDMXCSR, nullptr}, - {X86_INS_LDS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, - {X86_INS_FLDZ, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FLD1, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, - {X86_INS_FLD, &Capstone2LlvmIrTranslatorX86_impl::translateFld}, - {X86_INS_LEA, &Capstone2LlvmIrTranslatorX86_impl::translateLea}, - {X86_INS_LEAVE, &Capstone2LlvmIrTranslatorX86_impl::translateLeave}, - {X86_INS_LES, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, - {X86_INS_LFENCE, nullptr}, - {X86_INS_LFS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, - {X86_INS_LGDT, nullptr}, - {X86_INS_LGS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, - {X86_INS_LIDT, nullptr}, - {X86_INS_LLDT, nullptr}, - {X86_INS_LMSW, nullptr}, - {X86_INS_OR, &Capstone2LlvmIrTranslatorX86_impl::translateOr}, - {X86_INS_SUB, &Capstone2LlvmIrTranslatorX86_impl::translateSub}, - {X86_INS_XOR, &Capstone2LlvmIrTranslatorX86_impl::translateXor}, - {X86_INS_LODSB, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, - {X86_INS_LODSD, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, - {X86_INS_LODSQ, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, - {X86_INS_LODSW, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, - {X86_INS_LOOP, &Capstone2LlvmIrTranslatorX86_impl::translateLoop}, - {X86_INS_LOOPE, &Capstone2LlvmIrTranslatorX86_impl::translateLoop}, - {X86_INS_LOOPNE, &Capstone2LlvmIrTranslatorX86_impl::translateLoop}, - {X86_INS_RETF, &Capstone2LlvmIrTranslatorX86_impl::translateRet}, - {X86_INS_RETFQ, &Capstone2LlvmIrTranslatorX86_impl::translateRet}, - {X86_INS_LSL, nullptr}, - {X86_INS_LSS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, - {X86_INS_LTR, nullptr}, - {X86_INS_XADD, &Capstone2LlvmIrTranslatorX86_impl::translateAdd}, - {X86_INS_LZCNT, nullptr}, - {X86_INS_MASKMOVDQU, nullptr}, - {X86_INS_MAXPD, nullptr}, - {X86_INS_MAXPS, nullptr}, - {X86_INS_MAXSD, nullptr}, - {X86_INS_MAXSS, nullptr}, - {X86_INS_MFENCE, nullptr}, - {X86_INS_MINPD, nullptr}, - {X86_INS_MINPS, nullptr}, - {X86_INS_MINSD, nullptr}, - {X86_INS_MINSS, nullptr}, - {X86_INS_CVTPD2PI, nullptr}, - {X86_INS_CVTPI2PD, nullptr}, - {X86_INS_CVTPI2PS, nullptr}, - {X86_INS_CVTPS2PI, nullptr}, - {X86_INS_CVTTPD2PI, nullptr}, - {X86_INS_CVTTPS2PI, nullptr}, - {X86_INS_EMMS, nullptr}, - {X86_INS_MASKMOVQ, nullptr}, - {X86_INS_MOVD, nullptr}, - {X86_INS_MOVDQ2Q, nullptr}, - {X86_INS_MOVNTQ, nullptr}, - {X86_INS_MOVQ2DQ, nullptr}, - {X86_INS_MOVQ, nullptr}, - {X86_INS_PABSB, nullptr}, - {X86_INS_PABSD, nullptr}, - {X86_INS_PABSW, nullptr}, - {X86_INS_PACKSSDW, nullptr}, - {X86_INS_PACKSSWB, nullptr}, - {X86_INS_PACKUSWB, nullptr}, - {X86_INS_PADDB, nullptr}, - {X86_INS_PADDD, nullptr}, - {X86_INS_PADDQ, nullptr}, - {X86_INS_PADDSB, nullptr}, - {X86_INS_PADDSW, nullptr}, - {X86_INS_PADDUSB, nullptr}, - {X86_INS_PADDUSW, nullptr}, - {X86_INS_PADDW, nullptr}, - {X86_INS_PALIGNR, nullptr}, - {X86_INS_PANDN, nullptr}, - {X86_INS_PAND, nullptr}, - {X86_INS_PAVGB, nullptr}, - {X86_INS_PAVGW, nullptr}, - {X86_INS_PCMPEQB, nullptr}, - {X86_INS_PCMPEQD, nullptr}, - {X86_INS_PCMPEQW, nullptr}, - {X86_INS_PCMPGTB, nullptr}, - {X86_INS_PCMPGTD, nullptr}, - {X86_INS_PCMPGTW, nullptr}, - {X86_INS_PEXTRW, nullptr}, - {X86_INS_PHADDSW, nullptr}, - {X86_INS_PHADDW, nullptr}, - {X86_INS_PHADDD, nullptr}, - {X86_INS_PHSUBD, nullptr}, - {X86_INS_PHSUBSW, nullptr}, - {X86_INS_PHSUBW, nullptr}, - {X86_INS_PINSRW, nullptr}, - {X86_INS_PMADDUBSW, nullptr}, - {X86_INS_PMADDWD, nullptr}, - {X86_INS_PMAXSW, nullptr}, - {X86_INS_PMAXUB, nullptr}, - {X86_INS_PMINSW, nullptr}, - {X86_INS_PMINUB, nullptr}, - {X86_INS_PMOVMSKB, nullptr}, - {X86_INS_PMULHRSW, nullptr}, - {X86_INS_PMULHUW, nullptr}, - {X86_INS_PMULHW, nullptr}, - {X86_INS_PMULLW, nullptr}, - {X86_INS_PMULUDQ, nullptr}, - {X86_INS_POR, nullptr}, - {X86_INS_PSADBW, nullptr}, - {X86_INS_PSHUFB, nullptr}, - {X86_INS_PSHUFW, nullptr}, - {X86_INS_PSIGNB, nullptr}, - {X86_INS_PSIGND, nullptr}, - {X86_INS_PSIGNW, nullptr}, - {X86_INS_PSLLD, nullptr}, - {X86_INS_PSLLQ, nullptr}, - {X86_INS_PSLLW, nullptr}, - {X86_INS_PSRAD, nullptr}, - {X86_INS_PSRAW, nullptr}, - {X86_INS_PSRLD, nullptr}, - {X86_INS_PSRLQ, nullptr}, - {X86_INS_PSRLW, nullptr}, - {X86_INS_PSUBB, nullptr}, - {X86_INS_PSUBD, nullptr}, - {X86_INS_PSUBQ, nullptr}, - {X86_INS_PSUBSB, nullptr}, - {X86_INS_PSUBSW, nullptr}, - {X86_INS_PSUBUSB, nullptr}, - {X86_INS_PSUBUSW, nullptr}, - {X86_INS_PSUBW, nullptr}, - {X86_INS_PUNPCKHBW, nullptr}, - {X86_INS_PUNPCKHDQ, nullptr}, - {X86_INS_PUNPCKHWD, nullptr}, - {X86_INS_PUNPCKLBW, nullptr}, - {X86_INS_PUNPCKLDQ, nullptr}, - {X86_INS_PUNPCKLWD, nullptr}, - {X86_INS_PXOR, nullptr}, - {X86_INS_MONITOR, nullptr}, - {X86_INS_MONTMUL, nullptr}, - {X86_INS_MOV, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, - {X86_INS_MOVABS, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, - {X86_INS_MOVBE, nullptr}, - {X86_INS_MOVDDUP, nullptr}, - {X86_INS_MOVDQA, nullptr}, - {X86_INS_MOVDQU, nullptr}, - {X86_INS_MOVHLPS, nullptr}, - {X86_INS_MOVHPD, nullptr}, - {X86_INS_MOVHPS, nullptr}, - {X86_INS_MOVLHPS, nullptr}, - {X86_INS_MOVLPD, nullptr}, - {X86_INS_MOVLPS, nullptr}, - {X86_INS_MOVMSKPD, nullptr}, - {X86_INS_MOVMSKPS, nullptr}, - {X86_INS_MOVNTDQA, nullptr}, - {X86_INS_MOVNTDQ, nullptr}, - {X86_INS_MOVNTI, nullptr}, - {X86_INS_MOVNTPD, nullptr}, - {X86_INS_MOVNTPS, nullptr}, - {X86_INS_MOVNTSD, nullptr}, - {X86_INS_MOVNTSS, nullptr}, - {X86_INS_MOVSB, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, - {X86_INS_MOVSD, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, - {X86_INS_MOVSHDUP, nullptr}, - {X86_INS_MOVSLDUP, nullptr}, - {X86_INS_MOVSQ, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, - {X86_INS_MOVSS, nullptr}, - {X86_INS_MOVSW, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, - {X86_INS_MOVSX, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, - {X86_INS_MOVSXD, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, - {X86_INS_MOVUPD, nullptr}, - {X86_INS_MOVUPS, nullptr}, - {X86_INS_MOVZX, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, - {X86_INS_MPSADBW, nullptr}, - {X86_INS_MUL, &Capstone2LlvmIrTranslatorX86_impl::translateMul}, - {X86_INS_MULPD, nullptr}, - {X86_INS_MULPS, nullptr}, - {X86_INS_MULSD, nullptr}, - {X86_INS_MULSS, nullptr}, - {X86_INS_MULX, nullptr}, - {X86_INS_FMUL, &Capstone2LlvmIrTranslatorX86_impl::translateFmul}, - {X86_INS_FIMUL, &Capstone2LlvmIrTranslatorX86_impl::translateFmul}, - {X86_INS_FMULP, &Capstone2LlvmIrTranslatorX86_impl::translateFmul}, - {X86_INS_MWAIT, nullptr}, - {X86_INS_NEG, &Capstone2LlvmIrTranslatorX86_impl::translateNeg}, - {X86_INS_NOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_NOT, &Capstone2LlvmIrTranslatorX86_impl::translateNot}, - {X86_INS_OUT, nullptr}, - {X86_INS_OUTSB, &Capstone2LlvmIrTranslatorX86_impl::translateOuts}, - {X86_INS_OUTSD, &Capstone2LlvmIrTranslatorX86_impl::translateOuts}, - {X86_INS_OUTSW, &Capstone2LlvmIrTranslatorX86_impl::translateOuts}, - {X86_INS_PACKUSDW, nullptr}, - {X86_INS_PAUSE, nullptr}, - {X86_INS_PAVGUSB, nullptr}, - {X86_INS_PBLENDVB, nullptr}, - {X86_INS_PBLENDW, nullptr}, - {X86_INS_PCLMULQDQ, nullptr}, - {X86_INS_PCMPEQQ, nullptr}, - {X86_INS_PCMPESTRI, nullptr}, - {X86_INS_PCMPESTRM, nullptr}, - {X86_INS_PCMPGTQ, nullptr}, - {X86_INS_PCMPISTRI, nullptr}, - {X86_INS_PCMPISTRM, nullptr}, - {X86_INS_PDEP, nullptr}, - {X86_INS_PEXT, nullptr}, - {X86_INS_PEXTRB, nullptr}, - {X86_INS_PEXTRD, nullptr}, - {X86_INS_PEXTRQ, nullptr}, - {X86_INS_PF2ID, nullptr}, - {X86_INS_PF2IW, nullptr}, - {X86_INS_PFACC, nullptr}, - {X86_INS_PFADD, nullptr}, - {X86_INS_PFCMPEQ, nullptr}, - {X86_INS_PFCMPGE, nullptr}, - {X86_INS_PFCMPGT, nullptr}, - {X86_INS_PFMAX, nullptr}, - {X86_INS_PFMIN, nullptr}, - {X86_INS_PFMUL, nullptr}, - {X86_INS_PFNACC, nullptr}, - {X86_INS_PFPNACC, nullptr}, - {X86_INS_PFRCPIT1, nullptr}, - {X86_INS_PFRCPIT2, nullptr}, - {X86_INS_PFRCP, nullptr}, - {X86_INS_PFRSQIT1, nullptr}, - {X86_INS_PFRSQRT, nullptr}, - {X86_INS_PFSUBR, nullptr}, - {X86_INS_PFSUB, nullptr}, - {X86_INS_PHMINPOSUW, nullptr}, - {X86_INS_PI2FD, nullptr}, - {X86_INS_PI2FW, nullptr}, - {X86_INS_PINSRB, nullptr}, - {X86_INS_PINSRD, nullptr}, - {X86_INS_PINSRQ, nullptr}, - {X86_INS_PMAXSB, nullptr}, - {X86_INS_PMAXSD, nullptr}, - {X86_INS_PMAXUD, nullptr}, - {X86_INS_PMAXUW, nullptr}, - {X86_INS_PMINSB, nullptr}, - {X86_INS_PMINSD, nullptr}, - {X86_INS_PMINUD, nullptr}, - {X86_INS_PMINUW, nullptr}, - {X86_INS_PMOVSXBD, nullptr}, - {X86_INS_PMOVSXBQ, nullptr}, - {X86_INS_PMOVSXBW, nullptr}, - {X86_INS_PMOVSXDQ, nullptr}, - {X86_INS_PMOVSXWD, nullptr}, - {X86_INS_PMOVSXWQ, nullptr}, - {X86_INS_PMOVZXBD, nullptr}, - {X86_INS_PMOVZXBQ, nullptr}, - {X86_INS_PMOVZXBW, nullptr}, - {X86_INS_PMOVZXDQ, nullptr}, - {X86_INS_PMOVZXWD, nullptr}, - {X86_INS_PMOVZXWQ, nullptr}, - {X86_INS_PMULDQ, nullptr}, - {X86_INS_PMULHRW, nullptr}, - {X86_INS_PMULLD, nullptr}, - {X86_INS_POP, &Capstone2LlvmIrTranslatorX86_impl::translatePop}, - {X86_INS_POPAW, &Capstone2LlvmIrTranslatorX86_impl::translatePopa}, // X86_INS_POPAW == POPA - {X86_INS_POPAL, &Capstone2LlvmIrTranslatorX86_impl::translatePopa}, // X86_INS_POPAL == POPAD - {X86_INS_POPCNT, nullptr}, - {X86_INS_POPF, &Capstone2LlvmIrTranslatorX86_impl::translatePopEflags}, - {X86_INS_POPFD, &Capstone2LlvmIrTranslatorX86_impl::translatePopEflags}, - {X86_INS_POPFQ, &Capstone2LlvmIrTranslatorX86_impl::translatePopEflags}, - {X86_INS_PREFETCH, nullptr}, - {X86_INS_PREFETCHNTA, nullptr}, - {X86_INS_PREFETCHT0, nullptr}, - {X86_INS_PREFETCHT1, nullptr}, - {X86_INS_PREFETCHT2, nullptr}, - {X86_INS_PREFETCHW, nullptr}, - {X86_INS_PSHUFD, nullptr}, - {X86_INS_PSHUFHW, nullptr}, - {X86_INS_PSHUFLW, nullptr}, - {X86_INS_PSLLDQ, nullptr}, - {X86_INS_PSRLDQ, nullptr}, - {X86_INS_PSWAPD, nullptr}, - {X86_INS_PTEST, nullptr}, - {X86_INS_PUNPCKHQDQ, nullptr}, - {X86_INS_PUNPCKLQDQ, nullptr}, - {X86_INS_PUSH, &Capstone2LlvmIrTranslatorX86_impl::translatePush}, - {X86_INS_PUSHAW, &Capstone2LlvmIrTranslatorX86_impl::translatePusha}, // X86_INS_PUSHAW = PUSHA - {X86_INS_PUSHAL, &Capstone2LlvmIrTranslatorX86_impl::translatePusha}, // X86_INS_PUSHAL = PUSHAD - {X86_INS_PUSHF, &Capstone2LlvmIrTranslatorX86_impl::translatePushEflags}, - {X86_INS_PUSHFD, &Capstone2LlvmIrTranslatorX86_impl::translatePushEflags}, - {X86_INS_PUSHFQ, &Capstone2LlvmIrTranslatorX86_impl::translatePushEflags}, - {X86_INS_RCL, &Capstone2LlvmIrTranslatorX86_impl::translateRcl}, - {X86_INS_RCPPS, nullptr}, - {X86_INS_RCPSS, nullptr}, - {X86_INS_RCR, &Capstone2LlvmIrTranslatorX86_impl::translateRcr}, - {X86_INS_RDFSBASE, nullptr}, - {X86_INS_RDGSBASE, nullptr}, - {X86_INS_RDMSR, nullptr}, - {X86_INS_RDPMC, nullptr}, - {X86_INS_RDRAND, nullptr}, - {X86_INS_RDSEED, nullptr}, - {X86_INS_RDTSC, &Capstone2LlvmIrTranslatorX86_impl::translateRdtsc}, - {X86_INS_RDTSCP, &Capstone2LlvmIrTranslatorX86_impl::translateRdtscp}, - {X86_INS_ROL, &Capstone2LlvmIrTranslatorX86_impl::translateRol}, - {X86_INS_ROR, &Capstone2LlvmIrTranslatorX86_impl::translateRor}, - {X86_INS_RORX, nullptr}, - {X86_INS_ROUNDPD, nullptr}, - {X86_INS_ROUNDPS, nullptr}, - {X86_INS_ROUNDSD, nullptr}, - {X86_INS_ROUNDSS, nullptr}, - {X86_INS_RSM, nullptr}, - {X86_INS_RSQRTPS, nullptr}, - {X86_INS_RSQRTSS, nullptr}, - {X86_INS_SAHF, &Capstone2LlvmIrTranslatorX86_impl::translateSahf}, - {X86_INS_SAL, &Capstone2LlvmIrTranslatorX86_impl::translateShiftLeft}, - {X86_INS_SALC, &Capstone2LlvmIrTranslatorX86_impl::translateSalc}, - {X86_INS_SAR, &Capstone2LlvmIrTranslatorX86_impl::translateShiftRight}, - {X86_INS_SARX, nullptr}, - {X86_INS_SBB, &Capstone2LlvmIrTranslatorX86_impl::translateSbb}, - {X86_INS_SCASB, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, - {X86_INS_SCASD, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, - {X86_INS_SCASQ, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, - {X86_INS_SCASW, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, - {X86_INS_SETAE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETA, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETBE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETB, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETGE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETG, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETLE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETL, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETNE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETNO, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETNP, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETNS, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETO, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETP, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SETS, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, - {X86_INS_SFENCE, nullptr}, - {X86_INS_SGDT, nullptr}, - {X86_INS_SHA1MSG1, nullptr}, - {X86_INS_SHA1MSG2, nullptr}, - {X86_INS_SHA1NEXTE, nullptr}, - {X86_INS_SHA1RNDS4, nullptr}, - {X86_INS_SHA256MSG1, nullptr}, - {X86_INS_SHA256MSG2, nullptr}, - {X86_INS_SHA256RNDS2, nullptr}, - {X86_INS_SHL, &Capstone2LlvmIrTranslatorX86_impl::translateShiftLeft}, - {X86_INS_SHLD, &Capstone2LlvmIrTranslatorX86_impl::translateShld}, - {X86_INS_SHLX, nullptr}, - {X86_INS_SHR, &Capstone2LlvmIrTranslatorX86_impl::translateShiftRight}, - {X86_INS_SHRD, &Capstone2LlvmIrTranslatorX86_impl::translateShrd}, - {X86_INS_SHRX, nullptr}, - {X86_INS_SHUFPD, nullptr}, - {X86_INS_SHUFPS, nullptr}, - {X86_INS_SIDT, nullptr}, - {X86_INS_FSIN, &Capstone2LlvmIrTranslatorX86_impl::translateFsin}, - {X86_INS_SKINIT, nullptr}, - {X86_INS_SLDT, nullptr}, - {X86_INS_SMSW, nullptr}, - {X86_INS_SQRTPD, nullptr}, - {X86_INS_SQRTPS, nullptr}, - {X86_INS_SQRTSD, nullptr}, - {X86_INS_SQRTSS, nullptr}, - {X86_INS_FSQRT, &Capstone2LlvmIrTranslatorX86_impl::translateFsqrt}, - {X86_INS_STAC, nullptr}, - {X86_INS_STC, &Capstone2LlvmIrTranslatorX86_impl::translateStc}, - {X86_INS_STD, &Capstone2LlvmIrTranslatorX86_impl::translateStd}, - {X86_INS_STGI, nullptr}, - {X86_INS_STI, nullptr}, - {X86_INS_STMXCSR, nullptr}, - {X86_INS_STOSB, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, - {X86_INS_STOSD, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, - {X86_INS_STOSQ, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, - {X86_INS_STOSW, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, - {X86_INS_STR, nullptr}, - {X86_INS_FST, &Capstone2LlvmIrTranslatorX86_impl::translateFst}, - {X86_INS_FSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFst}, - {X86_INS_FSTPNCE, nullptr}, - {X86_INS_FXCH, &Capstone2LlvmIrTranslatorX86_impl::translateFxch}, - {X86_INS_SUBPD, nullptr}, - {X86_INS_SUBPS, nullptr}, - {X86_INS_FSUBR, &Capstone2LlvmIrTranslatorX86_impl::translateFsubr}, - {X86_INS_FISUBR, &Capstone2LlvmIrTranslatorX86_impl::translateFsubr}, - {X86_INS_FSUBRP, &Capstone2LlvmIrTranslatorX86_impl::translateFsubr}, - {X86_INS_SUBSD, nullptr}, - {X86_INS_SUBSS, nullptr}, - {X86_INS_FSUB, &Capstone2LlvmIrTranslatorX86_impl::translateFsub}, - {X86_INS_FISUB, &Capstone2LlvmIrTranslatorX86_impl::translateFsub}, - {X86_INS_FSUBP, &Capstone2LlvmIrTranslatorX86_impl::translateFsub}, - {X86_INS_SWAPGS, nullptr}, - {X86_INS_SYSCALL, nullptr}, - {X86_INS_SYSENTER, nullptr}, - {X86_INS_SYSEXIT, nullptr}, - {X86_INS_SYSRET, nullptr}, - {X86_INS_T1MSKC, nullptr}, - {X86_INS_TEST, &Capstone2LlvmIrTranslatorX86_impl::translateAnd}, - {X86_INS_UD2, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_FTST, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_TZCNT, nullptr}, - {X86_INS_TZMSK, nullptr}, - {X86_INS_FUCOMPI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FUCOMI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FUCOMPP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FUCOMP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_FUCOM, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, - {X86_INS_UD1, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_UNPCKHPD, nullptr}, - {X86_INS_UNPCKHPS, nullptr}, - {X86_INS_UNPCKLPD, nullptr}, - {X86_INS_UNPCKLPS, nullptr}, - {X86_INS_VADDPD, nullptr}, - {X86_INS_VADDPS, nullptr}, - {X86_INS_VADDSD, nullptr}, - {X86_INS_VADDSS, nullptr}, - {X86_INS_VADDSUBPD, nullptr}, - {X86_INS_VADDSUBPS, nullptr}, - {X86_INS_VAESDECLAST, nullptr}, - {X86_INS_VAESDEC, nullptr}, - {X86_INS_VAESENCLAST, nullptr}, - {X86_INS_VAESENC, nullptr}, - {X86_INS_VAESIMC, nullptr}, - {X86_INS_VAESKEYGENASSIST, nullptr}, - {X86_INS_VALIGND, nullptr}, - {X86_INS_VALIGNQ, nullptr}, - {X86_INS_VANDNPD, nullptr}, - {X86_INS_VANDNPS, nullptr}, - {X86_INS_VANDPD, nullptr}, - {X86_INS_VANDPS, nullptr}, - {X86_INS_VBLENDMPD, nullptr}, - {X86_INS_VBLENDMPS, nullptr}, - {X86_INS_VBLENDPD, nullptr}, - {X86_INS_VBLENDPS, nullptr}, - {X86_INS_VBLENDVPD, nullptr}, - {X86_INS_VBLENDVPS, nullptr}, - {X86_INS_VBROADCASTF128, nullptr}, - {X86_INS_VBROADCASTI32X4, nullptr}, - {X86_INS_VBROADCASTI64X4, nullptr}, - {X86_INS_VBROADCASTSD, nullptr}, - {X86_INS_VBROADCASTSS, nullptr}, - {X86_INS_VCOMPRESSPD, nullptr}, - {X86_INS_VCOMPRESSPS, nullptr}, - {X86_INS_VCVTDQ2PD, nullptr}, - {X86_INS_VCVTDQ2PS, nullptr}, - {X86_INS_VCVTPD2DQ, nullptr}, - {X86_INS_VCVTPD2PS, nullptr}, - {X86_INS_VCVTPD2UDQ, nullptr}, - {X86_INS_VCVTPH2PS, nullptr}, - {X86_INS_VCVTPS2DQ, nullptr}, - {X86_INS_VCVTPS2PD, nullptr}, - {X86_INS_VCVTPS2PH, nullptr}, - {X86_INS_VCVTPS2UDQ, nullptr}, - {X86_INS_VCVTSD2SI, nullptr}, - {X86_INS_VCVTSD2USI, nullptr}, - {X86_INS_VCVTSS2SI, nullptr}, - {X86_INS_VCVTSS2USI, nullptr}, - {X86_INS_VCVTTPD2DQ, nullptr}, - {X86_INS_VCVTTPD2UDQ, nullptr}, - {X86_INS_VCVTTPS2DQ, nullptr}, - {X86_INS_VCVTTPS2UDQ, nullptr}, - {X86_INS_VCVTUDQ2PD, nullptr}, - {X86_INS_VCVTUDQ2PS, nullptr}, - {X86_INS_VDIVPD, nullptr}, - {X86_INS_VDIVPS, nullptr}, - {X86_INS_VDIVSD, nullptr}, - {X86_INS_VDIVSS, nullptr}, - {X86_INS_VDPPD, nullptr}, - {X86_INS_VDPPS, nullptr}, - {X86_INS_VERR, nullptr}, - {X86_INS_VERW, nullptr}, - {X86_INS_VEXP2PD, nullptr}, - {X86_INS_VEXP2PS, nullptr}, - {X86_INS_VEXPANDPD, nullptr}, - {X86_INS_VEXPANDPS, nullptr}, - {X86_INS_VEXTRACTF128, nullptr}, - {X86_INS_VEXTRACTF32X4, nullptr}, - {X86_INS_VEXTRACTF64X4, nullptr}, - {X86_INS_VEXTRACTI128, nullptr}, - {X86_INS_VEXTRACTI32X4, nullptr}, - {X86_INS_VEXTRACTI64X4, nullptr}, - {X86_INS_VEXTRACTPS, nullptr}, - {X86_INS_VFMADD132PD, nullptr}, - {X86_INS_VFMADD132PS, nullptr}, - {X86_INS_VFMADDPD, nullptr}, - {X86_INS_VFMADD213PD, nullptr}, - {X86_INS_VFMADD231PD, nullptr}, - {X86_INS_VFMADDPS, nullptr}, - {X86_INS_VFMADD213PS, nullptr}, - {X86_INS_VFMADD231PS, nullptr}, - {X86_INS_VFMADDSD, nullptr}, - {X86_INS_VFMADD213SD, nullptr}, - {X86_INS_VFMADD132SD, nullptr}, - {X86_INS_VFMADD231SD, nullptr}, - {X86_INS_VFMADDSS, nullptr}, - {X86_INS_VFMADD213SS, nullptr}, - {X86_INS_VFMADD132SS, nullptr}, - {X86_INS_VFMADD231SS, nullptr}, - {X86_INS_VFMADDSUB132PD, nullptr}, - {X86_INS_VFMADDSUB132PS, nullptr}, - {X86_INS_VFMADDSUBPD, nullptr}, - {X86_INS_VFMADDSUB213PD, nullptr}, - {X86_INS_VFMADDSUB231PD, nullptr}, - {X86_INS_VFMADDSUBPS, nullptr}, - {X86_INS_VFMADDSUB213PS, nullptr}, - {X86_INS_VFMADDSUB231PS, nullptr}, - {X86_INS_VFMSUB132PD, nullptr}, - {X86_INS_VFMSUB132PS, nullptr}, - {X86_INS_VFMSUBADD132PD, nullptr}, - {X86_INS_VFMSUBADD132PS, nullptr}, - {X86_INS_VFMSUBADDPD, nullptr}, - {X86_INS_VFMSUBADD213PD, nullptr}, - {X86_INS_VFMSUBADD231PD, nullptr}, - {X86_INS_VFMSUBADDPS, nullptr}, - {X86_INS_VFMSUBADD213PS, nullptr}, - {X86_INS_VFMSUBADD231PS, nullptr}, - {X86_INS_VFMSUBPD, nullptr}, - {X86_INS_VFMSUB213PD, nullptr}, - {X86_INS_VFMSUB231PD, nullptr}, - {X86_INS_VFMSUBPS, nullptr}, - {X86_INS_VFMSUB213PS, nullptr}, - {X86_INS_VFMSUB231PS, nullptr}, - {X86_INS_VFMSUBSD, nullptr}, - {X86_INS_VFMSUB213SD, nullptr}, - {X86_INS_VFMSUB132SD, nullptr}, - {X86_INS_VFMSUB231SD, nullptr}, - {X86_INS_VFMSUBSS, nullptr}, - {X86_INS_VFMSUB213SS, nullptr}, - {X86_INS_VFMSUB132SS, nullptr}, - {X86_INS_VFMSUB231SS, nullptr}, - {X86_INS_VFNMADD132PD, nullptr}, - {X86_INS_VFNMADD132PS, nullptr}, - {X86_INS_VFNMADDPD, nullptr}, - {X86_INS_VFNMADD213PD, nullptr}, - {X86_INS_VFNMADD231PD, nullptr}, - {X86_INS_VFNMADDPS, nullptr}, - {X86_INS_VFNMADD213PS, nullptr}, - {X86_INS_VFNMADD231PS, nullptr}, - {X86_INS_VFNMADDSD, nullptr}, - {X86_INS_VFNMADD213SD, nullptr}, - {X86_INS_VFNMADD132SD, nullptr}, - {X86_INS_VFNMADD231SD, nullptr}, - {X86_INS_VFNMADDSS, nullptr}, - {X86_INS_VFNMADD213SS, nullptr}, - {X86_INS_VFNMADD132SS, nullptr}, - {X86_INS_VFNMADD231SS, nullptr}, - {X86_INS_VFNMSUB132PD, nullptr}, - {X86_INS_VFNMSUB132PS, nullptr}, - {X86_INS_VFNMSUBPD, nullptr}, - {X86_INS_VFNMSUB213PD, nullptr}, - {X86_INS_VFNMSUB231PD, nullptr}, - {X86_INS_VFNMSUBPS, nullptr}, - {X86_INS_VFNMSUB213PS, nullptr}, - {X86_INS_VFNMSUB231PS, nullptr}, - {X86_INS_VFNMSUBSD, nullptr}, - {X86_INS_VFNMSUB213SD, nullptr}, - {X86_INS_VFNMSUB132SD, nullptr}, - {X86_INS_VFNMSUB231SD, nullptr}, - {X86_INS_VFNMSUBSS, nullptr}, - {X86_INS_VFNMSUB213SS, nullptr}, - {X86_INS_VFNMSUB132SS, nullptr}, - {X86_INS_VFNMSUB231SS, nullptr}, - {X86_INS_VFRCZPD, nullptr}, - {X86_INS_VFRCZPS, nullptr}, - {X86_INS_VFRCZSD, nullptr}, - {X86_INS_VFRCZSS, nullptr}, - {X86_INS_VORPD, nullptr}, - {X86_INS_VORPS, nullptr}, - {X86_INS_VXORPD, nullptr}, - {X86_INS_VXORPS, nullptr}, - {X86_INS_VGATHERDPD, nullptr}, - {X86_INS_VGATHERDPS, nullptr}, - {X86_INS_VGATHERPF0DPD, nullptr}, - {X86_INS_VGATHERPF0DPS, nullptr}, - {X86_INS_VGATHERPF0QPD, nullptr}, - {X86_INS_VGATHERPF0QPS, nullptr}, - {X86_INS_VGATHERPF1DPD, nullptr}, - {X86_INS_VGATHERPF1DPS, nullptr}, - {X86_INS_VGATHERPF1QPD, nullptr}, - {X86_INS_VGATHERPF1QPS, nullptr}, - {X86_INS_VGATHERQPD, nullptr}, - {X86_INS_VGATHERQPS, nullptr}, - {X86_INS_VHADDPD, nullptr}, - {X86_INS_VHADDPS, nullptr}, - {X86_INS_VHSUBPD, nullptr}, - {X86_INS_VHSUBPS, nullptr}, - {X86_INS_VINSERTF128, nullptr}, - {X86_INS_VINSERTF32X4, nullptr}, - {X86_INS_VINSERTF32X8, nullptr}, - {X86_INS_VINSERTF64X2, nullptr}, - {X86_INS_VINSERTF64X4, nullptr}, - {X86_INS_VINSERTI128, nullptr}, - {X86_INS_VINSERTI32X4, nullptr}, - {X86_INS_VINSERTI32X8, nullptr}, - {X86_INS_VINSERTI64X2, nullptr}, - {X86_INS_VINSERTI64X4, nullptr}, - {X86_INS_VINSERTPS, nullptr}, - {X86_INS_VLDDQU, nullptr}, - {X86_INS_VLDMXCSR, nullptr}, - {X86_INS_VMASKMOVDQU, nullptr}, - {X86_INS_VMASKMOVPD, nullptr}, - {X86_INS_VMASKMOVPS, nullptr}, - {X86_INS_VMAXPD, nullptr}, - {X86_INS_VMAXPS, nullptr}, - {X86_INS_VMAXSD, nullptr}, - {X86_INS_VMAXSS, nullptr}, - {X86_INS_VMCALL, nullptr}, - {X86_INS_VMCLEAR, nullptr}, - {X86_INS_VMFUNC, nullptr}, - {X86_INS_VMINPD, nullptr}, - {X86_INS_VMINPS, nullptr}, - {X86_INS_VMINSD, nullptr}, - {X86_INS_VMINSS, nullptr}, - {X86_INS_VMLAUNCH, nullptr}, - {X86_INS_VMLOAD, nullptr}, - {X86_INS_VMMCALL, nullptr}, - {X86_INS_VMOVQ, nullptr}, - {X86_INS_VMOVDDUP, nullptr}, - {X86_INS_VMOVD, nullptr}, - {X86_INS_VMOVDQA32, nullptr}, - {X86_INS_VMOVDQA64, nullptr}, - {X86_INS_VMOVDQA, nullptr}, - {X86_INS_VMOVDQU16, nullptr}, - {X86_INS_VMOVDQU32, nullptr}, - {X86_INS_VMOVDQU64, nullptr}, - {X86_INS_VMOVDQU8, nullptr}, - {X86_INS_VMOVDQU, nullptr}, - {X86_INS_VMOVHLPS, nullptr}, - {X86_INS_VMOVHPD, nullptr}, - {X86_INS_VMOVHPS, nullptr}, - {X86_INS_VMOVLHPS, nullptr}, - {X86_INS_VMOVLPD, nullptr}, - {X86_INS_VMOVLPS, nullptr}, - {X86_INS_VMOVMSKPD, nullptr}, - {X86_INS_VMOVMSKPS, nullptr}, - {X86_INS_VMOVNTDQA, nullptr}, - {X86_INS_VMOVNTDQ, nullptr}, - {X86_INS_VMOVNTPD, nullptr}, - {X86_INS_VMOVNTPS, nullptr}, - {X86_INS_VMOVSD, nullptr}, - {X86_INS_VMOVSHDUP, nullptr}, - {X86_INS_VMOVSLDUP, nullptr}, - {X86_INS_VMOVSS, nullptr}, - {X86_INS_VMOVUPD, nullptr}, - {X86_INS_VMOVUPS, nullptr}, - {X86_INS_VMPSADBW, nullptr}, - {X86_INS_VMPTRLD, nullptr}, - {X86_INS_VMPTRST, nullptr}, - {X86_INS_VMREAD, nullptr}, - {X86_INS_VMRESUME, nullptr}, - {X86_INS_VMRUN, nullptr}, - {X86_INS_VMSAVE, nullptr}, - {X86_INS_VMULPD, nullptr}, - {X86_INS_VMULPS, nullptr}, - {X86_INS_VMULSD, nullptr}, - {X86_INS_VMULSS, nullptr}, - {X86_INS_VMWRITE, nullptr}, - {X86_INS_VMXOFF, nullptr}, - {X86_INS_VMXON, nullptr}, - {X86_INS_VPABSB, nullptr}, - {X86_INS_VPABSD, nullptr}, - {X86_INS_VPABSQ, nullptr}, - {X86_INS_VPABSW, nullptr}, - {X86_INS_VPACKSSDW, nullptr}, - {X86_INS_VPACKSSWB, nullptr}, - {X86_INS_VPACKUSDW, nullptr}, - {X86_INS_VPACKUSWB, nullptr}, - {X86_INS_VPADDB, nullptr}, - {X86_INS_VPADDD, nullptr}, - {X86_INS_VPADDQ, nullptr}, - {X86_INS_VPADDSB, nullptr}, - {X86_INS_VPADDSW, nullptr}, - {X86_INS_VPADDUSB, nullptr}, - {X86_INS_VPADDUSW, nullptr}, - {X86_INS_VPADDW, nullptr}, - {X86_INS_VPALIGNR, nullptr}, - {X86_INS_VPANDD, nullptr}, - {X86_INS_VPANDND, nullptr}, - {X86_INS_VPANDNQ, nullptr}, - {X86_INS_VPANDN, nullptr}, - {X86_INS_VPANDQ, nullptr}, - {X86_INS_VPAND, nullptr}, - {X86_INS_VPAVGB, nullptr}, - {X86_INS_VPAVGW, nullptr}, - {X86_INS_VPBLENDD, nullptr}, - {X86_INS_VPBLENDMB, nullptr}, - {X86_INS_VPBLENDMD, nullptr}, - {X86_INS_VPBLENDMQ, nullptr}, - {X86_INS_VPBLENDMW, nullptr}, - {X86_INS_VPBLENDVB, nullptr}, - {X86_INS_VPBLENDW, nullptr}, - {X86_INS_VPBROADCASTB, nullptr}, - {X86_INS_VPBROADCASTD, nullptr}, - {X86_INS_VPBROADCASTMB2Q, nullptr}, - {X86_INS_VPBROADCASTMW2D, nullptr}, - {X86_INS_VPBROADCASTQ, nullptr}, - {X86_INS_VPBROADCASTW, nullptr}, - {X86_INS_VPCLMULQDQ, nullptr}, - {X86_INS_VPCMOV, nullptr}, - {X86_INS_VPCMPB, nullptr}, - {X86_INS_VPCMPD, nullptr}, - {X86_INS_VPCMPEQB, nullptr}, - {X86_INS_VPCMPEQD, nullptr}, - {X86_INS_VPCMPEQQ, nullptr}, - {X86_INS_VPCMPEQW, nullptr}, - {X86_INS_VPCMPESTRI, nullptr}, - {X86_INS_VPCMPESTRM, nullptr}, - {X86_INS_VPCMPGTB, nullptr}, - {X86_INS_VPCMPGTD, nullptr}, - {X86_INS_VPCMPGTQ, nullptr}, - {X86_INS_VPCMPGTW, nullptr}, - {X86_INS_VPCMPISTRI, nullptr}, - {X86_INS_VPCMPISTRM, nullptr}, - {X86_INS_VPCMPQ, nullptr}, - {X86_INS_VPCMPUB, nullptr}, - {X86_INS_VPCMPUD, nullptr}, - {X86_INS_VPCMPUQ, nullptr}, - {X86_INS_VPCMPUW, nullptr}, - {X86_INS_VPCMPW, nullptr}, - {X86_INS_VPCOMB, nullptr}, - {X86_INS_VPCOMD, nullptr}, - {X86_INS_VPCOMPRESSD, nullptr}, - {X86_INS_VPCOMPRESSQ, nullptr}, - {X86_INS_VPCOMQ, nullptr}, - {X86_INS_VPCOMUB, nullptr}, - {X86_INS_VPCOMUD, nullptr}, - {X86_INS_VPCOMUQ, nullptr}, - {X86_INS_VPCOMUW, nullptr}, - {X86_INS_VPCOMW, nullptr}, - {X86_INS_VPCONFLICTD, nullptr}, - {X86_INS_VPCONFLICTQ, nullptr}, - {X86_INS_VPERM2F128, nullptr}, - {X86_INS_VPERM2I128, nullptr}, - {X86_INS_VPERMD, nullptr}, - {X86_INS_VPERMI2D, nullptr}, - {X86_INS_VPERMI2PD, nullptr}, - {X86_INS_VPERMI2PS, nullptr}, - {X86_INS_VPERMI2Q, nullptr}, - {X86_INS_VPERMIL2PD, nullptr}, - {X86_INS_VPERMIL2PS, nullptr}, - {X86_INS_VPERMILPD, nullptr}, - {X86_INS_VPERMILPS, nullptr}, - {X86_INS_VPERMPD, nullptr}, - {X86_INS_VPERMPS, nullptr}, - {X86_INS_VPERMQ, nullptr}, - {X86_INS_VPERMT2D, nullptr}, - {X86_INS_VPERMT2PD, nullptr}, - {X86_INS_VPERMT2PS, nullptr}, - {X86_INS_VPERMT2Q, nullptr}, - {X86_INS_VPEXPANDD, nullptr}, - {X86_INS_VPEXPANDQ, nullptr}, - {X86_INS_VPEXTRB, nullptr}, - {X86_INS_VPEXTRD, nullptr}, - {X86_INS_VPEXTRQ, nullptr}, - {X86_INS_VPEXTRW, nullptr}, - {X86_INS_VPGATHERDD, nullptr}, - {X86_INS_VPGATHERDQ, nullptr}, - {X86_INS_VPGATHERQD, nullptr}, - {X86_INS_VPGATHERQQ, nullptr}, - {X86_INS_VPHADDBD, nullptr}, - {X86_INS_VPHADDBQ, nullptr}, - {X86_INS_VPHADDBW, nullptr}, - {X86_INS_VPHADDDQ, nullptr}, - {X86_INS_VPHADDD, nullptr}, - {X86_INS_VPHADDSW, nullptr}, - {X86_INS_VPHADDUBD, nullptr}, - {X86_INS_VPHADDUBQ, nullptr}, - {X86_INS_VPHADDUBW, nullptr}, - {X86_INS_VPHADDUDQ, nullptr}, - {X86_INS_VPHADDUWD, nullptr}, - {X86_INS_VPHADDUWQ, nullptr}, - {X86_INS_VPHADDWD, nullptr}, - {X86_INS_VPHADDWQ, nullptr}, - {X86_INS_VPHADDW, nullptr}, - {X86_INS_VPHMINPOSUW, nullptr}, - {X86_INS_VPHSUBBW, nullptr}, - {X86_INS_VPHSUBDQ, nullptr}, - {X86_INS_VPHSUBD, nullptr}, - {X86_INS_VPHSUBSW, nullptr}, - {X86_INS_VPHSUBWD, nullptr}, - {X86_INS_VPHSUBW, nullptr}, - {X86_INS_VPINSRB, nullptr}, - {X86_INS_VPINSRD, nullptr}, - {X86_INS_VPINSRQ, nullptr}, - {X86_INS_VPINSRW, nullptr}, - {X86_INS_VPLZCNTD, nullptr}, - {X86_INS_VPLZCNTQ, nullptr}, - {X86_INS_VPMACSDD, nullptr}, - {X86_INS_VPMACSDQH, nullptr}, - {X86_INS_VPMACSDQL, nullptr}, - {X86_INS_VPMACSSDD, nullptr}, - {X86_INS_VPMACSSDQH, nullptr}, - {X86_INS_VPMACSSDQL, nullptr}, - {X86_INS_VPMACSSWD, nullptr}, - {X86_INS_VPMACSSWW, nullptr}, - {X86_INS_VPMACSWD, nullptr}, - {X86_INS_VPMACSWW, nullptr}, - {X86_INS_VPMADCSSWD, nullptr}, - {X86_INS_VPMADCSWD, nullptr}, - {X86_INS_VPMADDUBSW, nullptr}, - {X86_INS_VPMADDWD, nullptr}, - {X86_INS_VPMASKMOVD, nullptr}, - {X86_INS_VPMASKMOVQ, nullptr}, - {X86_INS_VPMAXSB, nullptr}, - {X86_INS_VPMAXSD, nullptr}, - {X86_INS_VPMAXSQ, nullptr}, - {X86_INS_VPMAXSW, nullptr}, - {X86_INS_VPMAXUB, nullptr}, - {X86_INS_VPMAXUD, nullptr}, - {X86_INS_VPMAXUQ, nullptr}, - {X86_INS_VPMAXUW, nullptr}, - {X86_INS_VPMINSB, nullptr}, - {X86_INS_VPMINSD, nullptr}, - {X86_INS_VPMINSQ, nullptr}, - {X86_INS_VPMINSW, nullptr}, - {X86_INS_VPMINUB, nullptr}, - {X86_INS_VPMINUD, nullptr}, - {X86_INS_VPMINUQ, nullptr}, - {X86_INS_VPMINUW, nullptr}, - {X86_INS_VPMOVDB, nullptr}, - {X86_INS_VPMOVDW, nullptr}, - {X86_INS_VPMOVM2B, nullptr}, - {X86_INS_VPMOVM2D, nullptr}, - {X86_INS_VPMOVM2Q, nullptr}, - {X86_INS_VPMOVM2W, nullptr}, - {X86_INS_VPMOVMSKB, nullptr}, - {X86_INS_VPMOVQB, nullptr}, - {X86_INS_VPMOVQD, nullptr}, - {X86_INS_VPMOVQW, nullptr}, - {X86_INS_VPMOVSDB, nullptr}, - {X86_INS_VPMOVSDW, nullptr}, - {X86_INS_VPMOVSQB, nullptr}, - {X86_INS_VPMOVSQD, nullptr}, - {X86_INS_VPMOVSQW, nullptr}, - {X86_INS_VPMOVSXBD, nullptr}, - {X86_INS_VPMOVSXBQ, nullptr}, - {X86_INS_VPMOVSXBW, nullptr}, - {X86_INS_VPMOVSXDQ, nullptr}, - {X86_INS_VPMOVSXWD, nullptr}, - {X86_INS_VPMOVSXWQ, nullptr}, - {X86_INS_VPMOVUSDB, nullptr}, - {X86_INS_VPMOVUSDW, nullptr}, - {X86_INS_VPMOVUSQB, nullptr}, - {X86_INS_VPMOVUSQD, nullptr}, - {X86_INS_VPMOVUSQW, nullptr}, - {X86_INS_VPMOVZXBD, nullptr}, - {X86_INS_VPMOVZXBQ, nullptr}, - {X86_INS_VPMOVZXBW, nullptr}, - {X86_INS_VPMOVZXDQ, nullptr}, - {X86_INS_VPMOVZXWD, nullptr}, - {X86_INS_VPMOVZXWQ, nullptr}, - {X86_INS_VPMULDQ, nullptr}, - {X86_INS_VPMULHRSW, nullptr}, - {X86_INS_VPMULHUW, nullptr}, - {X86_INS_VPMULHW, nullptr}, - {X86_INS_VPMULLD, nullptr}, - {X86_INS_VPMULLQ, nullptr}, - {X86_INS_VPMULLW, nullptr}, - {X86_INS_VPMULUDQ, nullptr}, - {X86_INS_VPORD, nullptr}, - {X86_INS_VPORQ, nullptr}, - {X86_INS_VPOR, nullptr}, - {X86_INS_VPPERM, nullptr}, - {X86_INS_VPROTB, nullptr}, - {X86_INS_VPROTD, nullptr}, - {X86_INS_VPROTQ, nullptr}, - {X86_INS_VPROTW, nullptr}, - {X86_INS_VPSADBW, nullptr}, - {X86_INS_VPSCATTERDD, nullptr}, - {X86_INS_VPSCATTERDQ, nullptr}, - {X86_INS_VPSCATTERQD, nullptr}, - {X86_INS_VPSCATTERQQ, nullptr}, - {X86_INS_VPSHAB, nullptr}, - {X86_INS_VPSHAD, nullptr}, - {X86_INS_VPSHAQ, nullptr}, - {X86_INS_VPSHAW, nullptr}, - {X86_INS_VPSHLB, nullptr}, - {X86_INS_VPSHLD, nullptr}, - {X86_INS_VPSHLQ, nullptr}, - {X86_INS_VPSHLW, nullptr}, - {X86_INS_VPSHUFB, nullptr}, - {X86_INS_VPSHUFD, nullptr}, - {X86_INS_VPSHUFHW, nullptr}, - {X86_INS_VPSHUFLW, nullptr}, - {X86_INS_VPSIGNB, nullptr}, - {X86_INS_VPSIGND, nullptr}, - {X86_INS_VPSIGNW, nullptr}, - {X86_INS_VPSLLDQ, nullptr}, - {X86_INS_VPSLLD, nullptr}, - {X86_INS_VPSLLQ, nullptr}, - {X86_INS_VPSLLVD, nullptr}, - {X86_INS_VPSLLVQ, nullptr}, - {X86_INS_VPSLLW, nullptr}, - {X86_INS_VPSRAD, nullptr}, - {X86_INS_VPSRAQ, nullptr}, - {X86_INS_VPSRAVD, nullptr}, - {X86_INS_VPSRAVQ, nullptr}, - {X86_INS_VPSRAW, nullptr}, - {X86_INS_VPSRLDQ, nullptr}, - {X86_INS_VPSRLD, nullptr}, - {X86_INS_VPSRLQ, nullptr}, - {X86_INS_VPSRLVD, nullptr}, - {X86_INS_VPSRLVQ, nullptr}, - {X86_INS_VPSRLW, nullptr}, - {X86_INS_VPSUBB, nullptr}, - {X86_INS_VPSUBD, nullptr}, - {X86_INS_VPSUBQ, nullptr}, - {X86_INS_VPSUBSB, nullptr}, - {X86_INS_VPSUBSW, nullptr}, - {X86_INS_VPSUBUSB, nullptr}, - {X86_INS_VPSUBUSW, nullptr}, - {X86_INS_VPSUBW, nullptr}, - {X86_INS_VPTESTMD, nullptr}, - {X86_INS_VPTESTMQ, nullptr}, - {X86_INS_VPTESTNMD, nullptr}, - {X86_INS_VPTESTNMQ, nullptr}, - {X86_INS_VPTEST, nullptr}, - {X86_INS_VPUNPCKHBW, nullptr}, - {X86_INS_VPUNPCKHDQ, nullptr}, - {X86_INS_VPUNPCKHQDQ, nullptr}, - {X86_INS_VPUNPCKHWD, nullptr}, - {X86_INS_VPUNPCKLBW, nullptr}, - {X86_INS_VPUNPCKLDQ, nullptr}, - {X86_INS_VPUNPCKLQDQ, nullptr}, - {X86_INS_VPUNPCKLWD, nullptr}, - {X86_INS_VPXORD, nullptr}, - {X86_INS_VPXORQ, nullptr}, - {X86_INS_VPXOR, nullptr}, - {X86_INS_VRCP14PD, nullptr}, - {X86_INS_VRCP14PS, nullptr}, - {X86_INS_VRCP14SD, nullptr}, - {X86_INS_VRCP14SS, nullptr}, - {X86_INS_VRCP28PD, nullptr}, - {X86_INS_VRCP28PS, nullptr}, - {X86_INS_VRCP28SD, nullptr}, - {X86_INS_VRCP28SS, nullptr}, - {X86_INS_VRCPPS, nullptr}, - {X86_INS_VRCPSS, nullptr}, - {X86_INS_VRNDSCALEPD, nullptr}, - {X86_INS_VRNDSCALEPS, nullptr}, - {X86_INS_VRNDSCALESD, nullptr}, - {X86_INS_VRNDSCALESS, nullptr}, - {X86_INS_VROUNDPD, nullptr}, - {X86_INS_VROUNDPS, nullptr}, - {X86_INS_VROUNDSD, nullptr}, - {X86_INS_VROUNDSS, nullptr}, - {X86_INS_VRSQRT14PD, nullptr}, - {X86_INS_VRSQRT14PS, nullptr}, - {X86_INS_VRSQRT14SD, nullptr}, - {X86_INS_VRSQRT14SS, nullptr}, - {X86_INS_VRSQRT28PD, nullptr}, - {X86_INS_VRSQRT28PS, nullptr}, - {X86_INS_VRSQRT28SD, nullptr}, - {X86_INS_VRSQRT28SS, nullptr}, - {X86_INS_VRSQRTPS, nullptr}, - {X86_INS_VRSQRTSS, nullptr}, - {X86_INS_VSCATTERDPD, nullptr}, - {X86_INS_VSCATTERDPS, nullptr}, - {X86_INS_VSCATTERPF0DPD, nullptr}, - {X86_INS_VSCATTERPF0DPS, nullptr}, - {X86_INS_VSCATTERPF0QPD, nullptr}, - {X86_INS_VSCATTERPF0QPS, nullptr}, - {X86_INS_VSCATTERPF1DPD, nullptr}, - {X86_INS_VSCATTERPF1DPS, nullptr}, - {X86_INS_VSCATTERPF1QPD, nullptr}, - {X86_INS_VSCATTERPF1QPS, nullptr}, - {X86_INS_VSCATTERQPD, nullptr}, - {X86_INS_VSCATTERQPS, nullptr}, - {X86_INS_VSHUFPD, nullptr}, - {X86_INS_VSHUFPS, nullptr}, - {X86_INS_VSQRTPD, nullptr}, - {X86_INS_VSQRTPS, nullptr}, - {X86_INS_VSQRTSD, nullptr}, - {X86_INS_VSQRTSS, nullptr}, - {X86_INS_VSTMXCSR, nullptr}, - {X86_INS_VSUBPD, nullptr}, - {X86_INS_VSUBPS, nullptr}, - {X86_INS_VSUBSD, nullptr}, - {X86_INS_VSUBSS, nullptr}, - {X86_INS_VTESTPD, nullptr}, - {X86_INS_VTESTPS, nullptr}, - {X86_INS_VUNPCKHPD, nullptr}, - {X86_INS_VUNPCKHPS, nullptr}, - {X86_INS_VUNPCKLPD, nullptr}, - {X86_INS_VUNPCKLPS, nullptr}, - {X86_INS_VZEROALL, nullptr}, - {X86_INS_VZEROUPPER, nullptr}, - {X86_INS_WAIT, nullptr}, - {X86_INS_WBINVD, nullptr}, - {X86_INS_WRFSBASE, nullptr}, - {X86_INS_WRGSBASE, nullptr}, - {X86_INS_WRMSR, nullptr}, - {X86_INS_XABORT, nullptr}, - {X86_INS_XACQUIRE, nullptr}, - {X86_INS_XBEGIN, nullptr}, - {X86_INS_XCHG, &Capstone2LlvmIrTranslatorX86_impl::translateXchg}, - {X86_INS_XCRYPTCBC, nullptr}, - {X86_INS_XCRYPTCFB, nullptr}, - {X86_INS_XCRYPTCTR, nullptr}, - {X86_INS_XCRYPTECB, nullptr}, - {X86_INS_XCRYPTOFB, nullptr}, - {X86_INS_XEND, nullptr}, - {X86_INS_XGETBV, nullptr}, - {X86_INS_XLATB, &Capstone2LlvmIrTranslatorX86_impl::translateXlatb}, - {X86_INS_XRELEASE, nullptr}, - {X86_INS_XRSTOR, nullptr}, - {X86_INS_XRSTOR64, nullptr}, - {X86_INS_XRSTORS, nullptr}, - {X86_INS_XRSTORS64, nullptr}, - {X86_INS_XSAVE, nullptr}, - {X86_INS_XSAVE64, nullptr}, - {X86_INS_XSAVEC, nullptr}, - {X86_INS_XSAVEC64, nullptr}, - {X86_INS_XSAVEOPT, nullptr}, - {X86_INS_XSAVEOPT64, nullptr}, - {X86_INS_XSAVES, nullptr}, - {X86_INS_XSAVES64, nullptr}, - {X86_INS_XSETBV, nullptr}, - {X86_INS_XSHA1, nullptr}, - {X86_INS_XSHA256, nullptr}, - {X86_INS_XSTORE, nullptr}, - {X86_INS_XTEST, nullptr}, - {X86_INS_FDISI8087_NOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_FENI8087_NOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - - // pseudo instructions - {X86_INS_CMPSS, nullptr}, - {X86_INS_CMPSD, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, - {X86_INS_CMPPS, nullptr}, - {X86_INS_CMPPD, nullptr}, - {X86_INS_VCMPSS, nullptr}, - {X86_INS_VCMPSD, nullptr}, - {X86_INS_VCMPPS, nullptr}, - {X86_INS_VCMPPD, nullptr}, - {X86_INS_ENDBR32, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - {X86_INS_ENDBR64, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, - - {X86_INS_ENDING, nullptr}, // mark the end of the list of insn -}; - -} // namespace capstone2llvmir -} // namespace retdec +/** + * @file src/capstone2llvmir/x86/x86_init.cpp + * @brief Initializations for X86 implementation of @c Capstone2LlvmIrTranslator. + * @copyright (c) 2017 Avast Software, licensed under the MIT license + */ + +#include "capstone2llvmir/x86/x86_impl.h" + +namespace retdec { +namespace capstone2llvmir { + +// +//============================================================================== +// Pure virtual methods from Capstone2LlvmIrTranslator_impl +//============================================================================== +// + +void Capstone2LlvmIrTranslatorX86_impl::initializeArchSpecific() +{ + initializeRegistersParentMap(); +} + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegNameMap() +{ + std::map r2n = + { + // x86_reg_rflags + // + {X86_REG_CF, "cf"}, + {X86_REG_PF, "pf"}, + {X86_REG_AF, "az"}, + {X86_REG_ZF, "zf"}, + {X86_REG_SF, "sf"}, + {X86_REG_TF, "tf"}, + {X86_REG_IF, "if"}, + {X86_REG_DF, "df"}, + {X86_REG_OF, "of"}, + {X86_REG_IOPL, "iopl"}, + {X86_REG_NT, "nt"}, + {X86_REG_RF, "rf"}, + {X86_REG_VM, "vm"}, + {X86_REG_AC, "ac"}, + {X86_REG_VIF, "vif"}, + {X86_REG_VIP, "vip"}, + {X86_REG_ID, "id"}, + + // x87_reg_status + // + {X87_REG_IE, "fpu_stat_IE"}, + {X87_REG_DE, "fpu_stat_DE"}, + {X87_REG_ZE, "fpu_stat_ZE"}, + {X87_REG_OE, "fpu_stat_OE"}, + {X87_REG_UE, "fpu_stat_UE"}, + {X87_REG_PE, "fpu_stat_PE"}, + {X87_REG_SF, "fpu_stat_SF"}, + {X87_REG_ES, "fpu_stat_ES"}, + {X87_REG_C0, "fpu_stat_C0"}, + {X87_REG_C1, "fpu_stat_C1"}, + {X87_REG_C2, "fpu_stat_C2"}, + {X87_REG_C3, "fpu_stat_C3"}, + {X87_REG_TOP, "fpu_stat_TOP"}, + {X87_REG_B, "fpu_stat_B"}, + + // x87_reg_control + // + {X87_REG_IM, "fpu_control_IM"}, + {X87_REG_DM, "fpu_control_DM"}, + {X87_REG_ZM, "fpu_control_ZM"}, + {X87_REG_OM, "fpu_control_OM"}, + {X87_REG_UM, "fpu_control_UM"}, + {X87_REG_PM, "fpu_control_PM"}, + {X87_REG_PC, "fpu_control_PC"}, + {X87_REG_RC, "fpu_control_RC"}, + {X87_REG_X, "fpu_control_X"}, + + // FPU data registers + // They are named as ST(X) in Capstone, which is not good for us. + // + {X86_REG_ST0, "st0"}, + {X86_REG_ST1, "st1"}, + {X86_REG_ST2, "st2"}, + {X86_REG_ST3, "st3"}, + {X86_REG_ST4, "st4"}, + {X86_REG_ST5, "st5"}, + {X86_REG_ST6, "st6"}, + {X86_REG_ST7, "st7"}, + }; + + _reg2name = std::move(r2n); +} + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegTypeMap() +{ + auto* i1 = llvm::IntegerType::getInt1Ty(_module->getContext()); + auto* i2 = llvm::IntegerType::getIntNTy(_module->getContext(), 2); + auto* i3 = llvm::IntegerType::getIntNTy(_module->getContext(), 3); + auto* i8 = llvm::IntegerType::getInt8Ty(_module->getContext()); + auto* i16 = llvm::IntegerType::getInt16Ty(_module->getContext()); + auto* i32 = llvm::IntegerType::getInt32Ty(_module->getContext()); + auto* i64 = llvm::IntegerType::getInt64Ty(_module->getContext()); + auto* i128 = llvm::IntegerType::getInt128Ty(_module->getContext()); + auto* i256 = llvm::IntegerType::getIntNTy(_module->getContext(), 256); + auto* i512 = llvm::IntegerType::getIntNTy(_module->getContext(), 512); + auto* fp64 = llvm::IntegerType::getDoubleTy(_module->getContext()); + auto* fp80 = llvm::IntegerType::getX86_FP80Ty(_module->getContext()); + + auto* defTy = _origBasicMode == CS_MODE_64 ? i64 : i32; + + std::map r2t = + { + // x86_reg + // + {X86_REG_AH, i8}, + {X86_REG_AL, i8}, + {X86_REG_CH, i8}, + {X86_REG_CL, i8}, + {X86_REG_DH, i8}, + {X86_REG_DL, i8}, + {X86_REG_BH, i8}, + {X86_REG_BL, i8}, + {X86_REG_SPL, i8}, + {X86_REG_BPL, i8}, + {X86_REG_DIL, i8}, + {X86_REG_SIL, i8}, + {X86_REG_R8B, i8}, + {X86_REG_R9B, i8}, + {X86_REG_R10B, i8}, + {X86_REG_R11B, i8}, + {X86_REG_R12B, i8}, + {X86_REG_R13B, i8}, + {X86_REG_R14B, i8}, + {X86_REG_R15B, i8}, + + {X86_REG_AX, i16}, + {X86_REG_CX, i16}, + {X86_REG_DX, i16}, + {X86_REG_BP, i16}, + {X86_REG_BX, i16}, + {X86_REG_DI, i16}, + {X86_REG_SP, i16}, + {X86_REG_SI, i16}, + {X86_REG_SS, i16}, + {X86_REG_CS, i16}, + {X86_REG_DS, i16}, + {X86_REG_ES, i16}, + {X86_REG_FS, i16}, + {X86_REG_GS, i16}, + {X86_REG_R8W, i16}, + {X86_REG_R9W, i16}, + {X86_REG_R10W, i16}, + {X86_REG_R11W, i16}, + {X86_REG_R12W, i16}, + {X86_REG_R13W, i16}, + {X86_REG_R14W, i16}, + {X86_REG_R15W, i16}, + {X86_REG_IP, i16}, + + {X86_REG_EAX, i32}, + {X86_REG_EBP, i32}, + {X86_REG_EBX, i32}, + {X86_REG_ECX, i32}, + {X86_REG_EDI, i32}, + {X86_REG_EDX, i32}, + {X86_REG_ESI, i32}, + {X86_REG_ESP, i32}, + {X86_REG_R8D, i32}, + {X86_REG_R9D, i32}, + {X86_REG_R10D, i32}, + {X86_REG_R11D, i32}, + {X86_REG_R12D, i32}, + {X86_REG_R13D, i32}, + {X86_REG_R14D, i32}, + {X86_REG_R15D, i32}, + {X86_REG_EIP, i32}, + {X86_REG_EIZ, i32}, + + {X86_REG_RAX, i64}, + {X86_REG_RBP, i64}, + {X86_REG_RBX, i64}, + {X86_REG_RCX, i64}, + {X86_REG_RDI, i64}, + {X86_REG_RDX, i64}, + {X86_REG_RIP, i64}, + {X86_REG_RIZ, i64}, + {X86_REG_RSI, i64}, + {X86_REG_RSP, i64}, + {X86_REG_R8, i64}, + {X86_REG_R9, i64}, + {X86_REG_R10, i64}, + {X86_REG_R11, i64}, + {X86_REG_R12, i64}, + {X86_REG_R13, i64}, + {X86_REG_R14, i64}, + {X86_REG_R15, i64}, + + {X86_REG_ST0, fp80}, + {X86_REG_ST1, fp80}, + {X86_REG_ST2, fp80}, + {X86_REG_ST3, fp80}, + {X86_REG_ST4, fp80}, + {X86_REG_ST5, fp80}, + {X86_REG_ST6, fp80}, + {X86_REG_ST7, fp80}, + + {X86_REG_FP0, fp64}, + {X86_REG_FP1, fp64}, + {X86_REG_FP2, fp64}, + {X86_REG_FP3, fp64}, + {X86_REG_FP4, fp64}, + {X86_REG_FP5, fp64}, + {X86_REG_FP6, fp64}, + {X86_REG_FP7, fp64}, + + {X86_REG_EFLAGS, defTy}, + {X86_REG_DR0, defTy}, + {X86_REG_DR1, defTy}, + {X86_REG_DR2, defTy}, + {X86_REG_DR3, defTy}, + {X86_REG_DR4, defTy}, + {X86_REG_DR5, defTy}, + {X86_REG_DR6, defTy}, + {X86_REG_DR7, defTy}, + {X86_REG_DR8, defTy}, + {X86_REG_DR9, defTy}, + {X86_REG_DR10, defTy}, + {X86_REG_DR11, defTy}, + {X86_REG_DR12, defTy}, + {X86_REG_DR13, defTy}, + {X86_REG_DR14, defTy}, + {X86_REG_DR15, defTy}, + + {X86_REG_CR0, defTy}, + {X86_REG_CR1, defTy}, + {X86_REG_CR2, defTy}, + {X86_REG_CR3, defTy}, + {X86_REG_CR4, defTy}, + {X86_REG_CR5, defTy}, + {X86_REG_CR6, defTy}, + {X86_REG_CR7, defTy}, + {X86_REG_CR8, defTy}, + {X86_REG_CR9, defTy}, + {X86_REG_CR10, defTy}, + {X86_REG_CR11, defTy}, + {X86_REG_CR12, defTy}, + {X86_REG_CR13, defTy}, + {X86_REG_CR14, defTy}, + {X86_REG_CR15, defTy}, + + {X86_REG_FPSW, defTy}, + + // opmask registers (AVX-512) + {X86_REG_K0, i64}, + {X86_REG_K1, i64}, + {X86_REG_K2, i64}, + {X86_REG_K3, i64}, + {X86_REG_K4, i64}, + {X86_REG_K5, i64}, + {X86_REG_K6, i64}, + {X86_REG_K7, i64}, + + // MMX + {X86_REG_MM0, i64}, + {X86_REG_MM1, i64}, + {X86_REG_MM2, i64}, + {X86_REG_MM3, i64}, + {X86_REG_MM4, i64}, + {X86_REG_MM5, i64}, + {X86_REG_MM6, i64}, + {X86_REG_MM7, i64}, + + // XMM + {X86_REG_XMM0, i128}, + {X86_REG_XMM1, i128}, + {X86_REG_XMM2, i128}, + {X86_REG_XMM3, i128}, + {X86_REG_XMM4, i128}, + {X86_REG_XMM5, i128}, + {X86_REG_XMM6, i128}, + {X86_REG_XMM7, i128}, + {X86_REG_XMM8, i128}, + {X86_REG_XMM9, i128}, + {X86_REG_XMM10, i128}, + {X86_REG_XMM11, i128}, + {X86_REG_XMM12, i128}, + {X86_REG_XMM13, i128}, + {X86_REG_XMM14, i128}, + {X86_REG_XMM15, i128}, + {X86_REG_XMM16, i128}, + {X86_REG_XMM17, i128}, + {X86_REG_XMM18, i128}, + {X86_REG_XMM19, i128}, + {X86_REG_XMM20, i128}, + {X86_REG_XMM21, i128}, + {X86_REG_XMM22, i128}, + {X86_REG_XMM23, i128}, + {X86_REG_XMM24, i128}, + {X86_REG_XMM25, i128}, + {X86_REG_XMM26, i128}, + {X86_REG_XMM27, i128}, + {X86_REG_XMM28, i128}, + {X86_REG_XMM29, i128}, + {X86_REG_XMM30, i128}, + {X86_REG_XMM31, i128}, + + // YMM + {X86_REG_YMM0, i256}, + {X86_REG_YMM1, i256}, + {X86_REG_YMM2, i256}, + {X86_REG_YMM3, i256}, + {X86_REG_YMM4, i256}, + {X86_REG_YMM5, i256}, + {X86_REG_YMM6, i256}, + {X86_REG_YMM7, i256}, + {X86_REG_YMM8, i256}, + {X86_REG_YMM9, i256}, + {X86_REG_YMM10, i256}, + {X86_REG_YMM11, i256}, + {X86_REG_YMM12, i256}, + {X86_REG_YMM13, i256}, + {X86_REG_YMM14, i256}, + {X86_REG_YMM15, i256}, + {X86_REG_YMM16, i256}, + {X86_REG_YMM17, i256}, + {X86_REG_YMM18, i256}, + {X86_REG_YMM19, i256}, + {X86_REG_YMM20, i256}, + {X86_REG_YMM21, i256}, + {X86_REG_YMM22, i256}, + {X86_REG_YMM23, i256}, + {X86_REG_YMM24, i256}, + {X86_REG_YMM25, i256}, + {X86_REG_YMM26, i256}, + {X86_REG_YMM27, i256}, + {X86_REG_YMM28, i256}, + {X86_REG_YMM29, i256}, + {X86_REG_YMM30, i256}, + {X86_REG_YMM31, i256}, + + // ZMM + {X86_REG_ZMM0, i512}, + {X86_REG_ZMM1, i512}, + {X86_REG_ZMM2, i512}, + {X86_REG_ZMM3, i512}, + {X86_REG_ZMM4, i512}, + {X86_REG_ZMM5, i512}, + {X86_REG_ZMM6, i512}, + {X86_REG_ZMM7, i512}, + {X86_REG_ZMM8, i512}, + {X86_REG_ZMM9, i512}, + {X86_REG_ZMM10, i512}, + {X86_REG_ZMM11, i512}, + {X86_REG_ZMM12, i512}, + {X86_REG_ZMM13, i512}, + {X86_REG_ZMM14, i512}, + {X86_REG_ZMM15, i512}, + {X86_REG_ZMM16, i512}, + {X86_REG_ZMM17, i512}, + {X86_REG_ZMM18, i512}, + {X86_REG_ZMM19, i512}, + {X86_REG_ZMM20, i512}, + {X86_REG_ZMM21, i512}, + {X86_REG_ZMM22, i512}, + {X86_REG_ZMM23, i512}, + {X86_REG_ZMM24, i512}, + {X86_REG_ZMM25, i512}, + {X86_REG_ZMM26, i512}, + {X86_REG_ZMM27, i512}, + {X86_REG_ZMM28, i512}, + {X86_REG_ZMM29, i512}, + {X86_REG_ZMM30, i512}, + {X86_REG_ZMM31, i512}, + + // x86_reg_rflags + // + {X86_REG_CF, i1}, + {X86_REG_PF, i1}, + {X86_REG_AF, i1}, + {X86_REG_ZF, i1}, + {X86_REG_SF, i1}, + {X86_REG_TF, i1}, + {X86_REG_IF, i1}, + {X86_REG_DF, i1}, + {X86_REG_OF, i1}, + {X86_REG_IOPL, i2}, + {X86_REG_NT, i1}, + {X86_REG_RF, i1}, + {X86_REG_VM, i1}, + {X86_REG_AC, i1}, + {X86_REG_VIF, i1}, + {X86_REG_VIP, i1}, + {X86_REG_ID, i1}, + + // x87_reg_status + // + {X87_REG_IE, i1}, + {X87_REG_DE, i1}, + {X87_REG_ZE, i1}, + {X87_REG_OE, i1}, + {X87_REG_UE, i1}, + {X87_REG_PE, i1}, + {X87_REG_SF, i1}, + {X87_REG_ES, i1}, + {X87_REG_C0, i1}, + {X87_REG_C1, i1}, + {X87_REG_C2, i1}, + {X87_REG_C3, i1}, + {X87_REG_TOP, i3}, + {X87_REG_B, i1}, + + // x87_reg_control + // + {X87_REG_IM, i1}, + {X87_REG_DM, i1}, + {X87_REG_ZM, i1}, + {X87_REG_OM, i1}, + {X87_REG_UM, i1}, + {X87_REG_PM, i1}, + {X87_REG_PC, i2}, + {X87_REG_RC, i2}, + {X87_REG_X, i1}, + }; + + _reg2type = std::move(r2t); +} + +void Capstone2LlvmIrTranslatorX86_impl::initializePseudoCallInstructionIDs() +{ + _callInsnIds = + { + X86_INS_CALL, + X86_INS_LCALL, + }; + + _returnInsnIds = + { + X86_INS_RET, + X86_INS_RETF, + X86_INS_RETFQ + }; + + _branchInsnIds = + { + X86_INS_JMP, + X86_INS_LJMP, + }; + + _condBranchInsnIds = + { + X86_INS_JCXZ, + X86_INS_JECXZ, + X86_INS_JRCXZ, + // + X86_INS_LOOP, + X86_INS_LOOPE, + X86_INS_LOOPNE, + // + X86_INS_JAE, + X86_INS_JA, + X86_INS_JBE, + X86_INS_JB, + X86_INS_JE, + X86_INS_JGE, + X86_INS_JG, + X86_INS_JLE, + X86_INS_JL, + X86_INS_JNE, + X86_INS_JNO, + X86_INS_JNP, + X86_INS_JNS, + X86_INS_JO, + X86_INS_JP, + X86_INS_JS, + }; + + _controlFlowInsnIds = + { + // Currently, all instructions can be categorized based on their + // IDs alone. + }; +} + +// +//============================================================================== +// x86-specific methods. +//============================================================================== +// + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMapToOther( + const std::vector& rs, + x86_reg other) +{ + for (auto r : rs) + { + if (r >= _reg2parentMap.size()) + { + throw GenericError("Register out of range."); + } + _reg2parentMap[r] = other; + } +} + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap() +{ + switch (_origBasicMode) + { + case CS_MODE_16: initializeRegistersParentMap16(); break; + case CS_MODE_32: initializeRegistersParentMap32(); break; + case CS_MODE_64: initializeRegistersParentMap64(); break; + default: + { + throw GenericError("Unhandled mode in " + "initializeRegistersParentMap()."); + break; + } + } +} + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap16() +{ + // Last element in vector is its own parent. + std::vector> rss = + { + {X86_REG_AH, X86_REG_AL, X86_REG_AX}, + {X86_REG_CH, X86_REG_CL, X86_REG_CX}, + {X86_REG_DH, X86_REG_DL, X86_REG_DX}, + {X86_REG_BH, X86_REG_BL, X86_REG_BX}, + {X86_REG_SPL, X86_REG_SP}, + {X86_REG_BPL, X86_REG_BP}, + {X86_REG_SIL, X86_REG_SI}, + {X86_REG_DIL, X86_REG_DI}, + {X86_REG_IP}, + }; + + for (std::vector& rs : rss) + { + initializeRegistersParentMapToOther(rs, rs.back()); + } +} + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap32() +{ + // Last element in vector is its own parent. + std::vector> rss = + { + {X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_EAX}, + {X86_REG_CH, X86_REG_CL, X86_REG_CX, X86_REG_ECX}, + {X86_REG_DH, X86_REG_DL, X86_REG_DX, X86_REG_EDX}, + {X86_REG_BH, X86_REG_BL, X86_REG_BX, X86_REG_EBX}, + {X86_REG_SPL, X86_REG_SP, X86_REG_ESP}, + {X86_REG_BPL, X86_REG_BP, X86_REG_EBP}, + {X86_REG_SIL, X86_REG_SI, X86_REG_ESI}, + {X86_REG_DIL, X86_REG_DI, X86_REG_EDI}, + {X86_REG_IP, X86_REG_EIP}, + {X86_REG_EIZ}, + }; + + for (std::vector& rs : rss) + { + initializeRegistersParentMapToOther(rs, rs.back()); + } +} + +void Capstone2LlvmIrTranslatorX86_impl::initializeRegistersParentMap64() +{ + // Last element in vector is its own parent. + std::vector> rss = + { + {X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_EAX, X86_REG_RAX}, + {X86_REG_CH, X86_REG_CL, X86_REG_CX, X86_REG_ECX, X86_REG_RCX}, + {X86_REG_DH, X86_REG_DL, X86_REG_DX, X86_REG_EDX, X86_REG_RDX}, + {X86_REG_BH, X86_REG_BL, X86_REG_BX, X86_REG_EBX, X86_REG_RBX}, + {X86_REG_SPL, X86_REG_SP, X86_REG_ESP, X86_REG_RSP}, + {X86_REG_BPL, X86_REG_BP, X86_REG_EBP, X86_REG_RBP}, + {X86_REG_SIL, X86_REG_SI, X86_REG_ESI, X86_REG_RSI}, + {X86_REG_DIL, X86_REG_DI, X86_REG_EDI, X86_REG_RDI}, + {X86_REG_IP, X86_REG_EIP, X86_REG_RIP}, + {X86_REG_EIZ, X86_REG_RIZ}, + {X86_REG_R8B, X86_REG_R8W, X86_REG_R8D, X86_REG_R8}, + {X86_REG_R9B, X86_REG_R9W, X86_REG_R9D, X86_REG_R9}, + {X86_REG_R10B, X86_REG_R10W, X86_REG_R10D, X86_REG_R10}, + {X86_REG_R11B, X86_REG_R11W, X86_REG_R11D, X86_REG_R11}, + {X86_REG_R12B, X86_REG_R12W, X86_REG_R12D, X86_REG_R12}, + {X86_REG_R13B, X86_REG_R13W, X86_REG_R13D, X86_REG_R13}, + {X86_REG_R14B, X86_REG_R14W, X86_REG_R14D, X86_REG_R14}, + {X86_REG_R15B, X86_REG_R15W, X86_REG_R15D, X86_REG_R15} + }; + + for (std::vector& rs : rss) + { + initializeRegistersParentMapToOther(rs, rs.back()); + } +} + +// +//============================================================================== +// Instruction translation map initialization. +//============================================================================== +// + +std::map< + std::size_t, + void (Capstone2LlvmIrTranslatorX86_impl::*)( + cs_insn* i, + cs_x86*, + llvm::IRBuilder<>&)> +Capstone2LlvmIrTranslatorX86_impl::_i2fm = +{ + {X86_INS_INVALID, nullptr}, + + {X86_INS_AAA, &Capstone2LlvmIrTranslatorX86_impl::translateAaa}, + {X86_INS_AAD, &Capstone2LlvmIrTranslatorX86_impl::translateAad}, + {X86_INS_AAM, &Capstone2LlvmIrTranslatorX86_impl::translateAam}, + {X86_INS_AAS, &Capstone2LlvmIrTranslatorX86_impl::translateAaa}, + {X86_INS_FABS, &Capstone2LlvmIrTranslatorX86_impl::translateFabs}, + {X86_INS_ADC, &Capstone2LlvmIrTranslatorX86_impl::translateAdc}, + {X86_INS_ADCX, &Capstone2LlvmIrTranslatorX86_impl::translateAdc}, + {X86_INS_ADD, &Capstone2LlvmIrTranslatorX86_impl::translateAdd}, + {X86_INS_ADDPD, nullptr}, + {X86_INS_ADDPS, nullptr}, + {X86_INS_ADDSD, nullptr}, + {X86_INS_ADDSS, nullptr}, + {X86_INS_ADDSUBPD, nullptr}, + {X86_INS_ADDSUBPS, nullptr}, + {X86_INS_FADD, &Capstone2LlvmIrTranslatorX86_impl::translateFadd}, + {X86_INS_FIADD, &Capstone2LlvmIrTranslatorX86_impl::translateFadd}, + {X86_INS_ADOX, &Capstone2LlvmIrTranslatorX86_impl::translateAdc}, + {X86_INS_AESDECLAST, nullptr}, + {X86_INS_AESDEC, nullptr}, + {X86_INS_AESENCLAST, nullptr}, + {X86_INS_AESENC, nullptr}, + {X86_INS_AESIMC, nullptr}, + {X86_INS_AESKEYGENASSIST, nullptr}, + {X86_INS_AND, &Capstone2LlvmIrTranslatorX86_impl::translateAnd}, + {X86_INS_ANDN, nullptr}, + {X86_INS_ANDNPD, nullptr}, + {X86_INS_ANDNPS, nullptr}, + {X86_INS_ANDPD, nullptr}, + {X86_INS_ANDPS, nullptr}, + {X86_INS_ARPL, nullptr}, + {X86_INS_BEXTR, nullptr}, + {X86_INS_BLCFILL, nullptr}, + {X86_INS_BLCI, nullptr}, + {X86_INS_BLCIC, nullptr}, + {X86_INS_BLCMSK, nullptr}, + {X86_INS_BLCS, nullptr}, + {X86_INS_BLENDPD, nullptr}, + {X86_INS_BLENDPS, nullptr}, + {X86_INS_BLENDVPD, nullptr}, + {X86_INS_BLENDVPS, nullptr}, + {X86_INS_BLSFILL, nullptr}, + {X86_INS_BLSI, nullptr}, + {X86_INS_BLSIC, nullptr}, + {X86_INS_BLSMSK, nullptr}, + {X86_INS_BLSR, nullptr}, + {X86_INS_BOUND, nullptr}, + {X86_INS_BSF, &Capstone2LlvmIrTranslatorX86_impl::translateBsf}, + {X86_INS_BSR, &Capstone2LlvmIrTranslatorX86_impl::translateBsf}, + {X86_INS_BSWAP, &Capstone2LlvmIrTranslatorX86_impl::translateBswap}, + {X86_INS_BT, &Capstone2LlvmIrTranslatorX86_impl::translateBt}, + {X86_INS_BTC, &Capstone2LlvmIrTranslatorX86_impl::translateBtc}, + {X86_INS_BTR, &Capstone2LlvmIrTranslatorX86_impl::translateBtr}, + {X86_INS_BTS, &Capstone2LlvmIrTranslatorX86_impl::translateBts}, + {X86_INS_BZHI, nullptr}, + {X86_INS_BNDMK, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_BNDCL, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_BNDCU, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_BNDMOV, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_BNDLDX, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_BNDSTX, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_CALL, &Capstone2LlvmIrTranslatorX86_impl::translateCall}, + {X86_INS_CBW, &Capstone2LlvmIrTranslatorX86_impl::translateCbw}, + {X86_INS_CDQ, &Capstone2LlvmIrTranslatorX86_impl::translateCdq}, + {X86_INS_CDQE, &Capstone2LlvmIrTranslatorX86_impl::translateCdqe}, + {X86_INS_FCHS, &Capstone2LlvmIrTranslatorX86_impl::translateFchs}, + {X86_INS_CLAC, nullptr}, + {X86_INS_CLC, &Capstone2LlvmIrTranslatorX86_impl::translateClc}, + {X86_INS_CLD, &Capstone2LlvmIrTranslatorX86_impl::translateCld}, + {X86_INS_CLFLUSH, nullptr}, + {X86_INS_CLFLUSHOPT, nullptr}, + {X86_INS_CLGI, nullptr}, + {X86_INS_CLI, &Capstone2LlvmIrTranslatorX86_impl::translateCli}, + {X86_INS_CLTS, nullptr}, + {X86_INS_CLWB, nullptr}, + {X86_INS_CMC, &Capstone2LlvmIrTranslatorX86_impl::translateCmc}, + {X86_INS_CMOVA, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVAE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVB, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVBE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_FCMOVBE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_FCMOVB, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_CMOVE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_FCMOVE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_CMOVG, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVGE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVL, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVLE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_FCMOVNBE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_FCMOVNB, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_CMOVNE, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_FCMOVNE, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_CMOVNO, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVNP, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_FCMOVNU, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_CMOVNS, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVO, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMOVP, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_FCMOVU, &Capstone2LlvmIrTranslatorX86_impl::translateFCMovCc}, + {X86_INS_CMOVS, &Capstone2LlvmIrTranslatorX86_impl::translateCMovCc}, + {X86_INS_CMP, &Capstone2LlvmIrTranslatorX86_impl::translateSub}, + {X86_INS_CMPSB, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, + {X86_INS_CMPSQ, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, + {X86_INS_CMPSW, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, + {X86_INS_CMPXCHG16B, &Capstone2LlvmIrTranslatorX86_impl::translateCmpxchg16b}, + {X86_INS_CMPXCHG, &Capstone2LlvmIrTranslatorX86_impl::translateCmpxchg}, + {X86_INS_CMPXCHG8B, &Capstone2LlvmIrTranslatorX86_impl::translateCmpxchg8b}, + {X86_INS_COMISD, nullptr}, + {X86_INS_COMISS, nullptr}, + {X86_INS_FCOMP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FCOMPI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FCOMI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FCOM, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FCOS, &Capstone2LlvmIrTranslatorX86_impl::translateFcos}, + {X86_INS_CPUID, &Capstone2LlvmIrTranslatorX86_impl::translateCpuid}, + {X86_INS_CQO, &Capstone2LlvmIrTranslatorX86_impl::translateCqo}, + {X86_INS_CRC32, nullptr}, + {X86_INS_CVTDQ2PD, nullptr}, + {X86_INS_CVTDQ2PS, nullptr}, + {X86_INS_CVTPD2DQ, nullptr}, + {X86_INS_CVTPD2PS, nullptr}, + {X86_INS_CVTPS2DQ, nullptr}, + {X86_INS_CVTPS2PD, nullptr}, + {X86_INS_CVTSD2SI, nullptr}, + {X86_INS_CVTSD2SS, nullptr}, + {X86_INS_CVTSI2SD, nullptr}, + {X86_INS_CVTSI2SS, nullptr}, + {X86_INS_CVTSS2SD, nullptr}, + {X86_INS_CVTSS2SI, nullptr}, + {X86_INS_CVTTPD2DQ, nullptr}, + {X86_INS_CVTTPS2DQ, nullptr}, + {X86_INS_CVTTSD2SI, nullptr}, + {X86_INS_CVTTSS2SI, nullptr}, + {X86_INS_CWD, &Capstone2LlvmIrTranslatorX86_impl::translateCwd}, + {X86_INS_CWDE, &Capstone2LlvmIrTranslatorX86_impl::translateCwde}, + {X86_INS_DAA, &Capstone2LlvmIrTranslatorX86_impl::translateDaaDas}, + {X86_INS_DAS, &Capstone2LlvmIrTranslatorX86_impl::translateDaaDas}, + {X86_INS_DATA16, nullptr}, + {X86_INS_DEC, &Capstone2LlvmIrTranslatorX86_impl::translateDec}, + {X86_INS_DIV, &Capstone2LlvmIrTranslatorX86_impl::translateDiv}, + {X86_INS_DIVPD, nullptr}, + {X86_INS_DIVPS, nullptr}, + {X86_INS_FDIVR, &Capstone2LlvmIrTranslatorX86_impl::translateFdivr}, + {X86_INS_FIDIVR, &Capstone2LlvmIrTranslatorX86_impl::translateFdivr}, + {X86_INS_FDIVRP, &Capstone2LlvmIrTranslatorX86_impl::translateFdivr}, + {X86_INS_DIVSD, nullptr}, + {X86_INS_DIVSS, nullptr}, + {X86_INS_FDIV, &Capstone2LlvmIrTranslatorX86_impl::translateFdiv}, + {X86_INS_FIDIV, &Capstone2LlvmIrTranslatorX86_impl::translateFdiv}, + {X86_INS_FDIVP, &Capstone2LlvmIrTranslatorX86_impl::translateFdiv}, + {X86_INS_DPPD, nullptr}, + {X86_INS_DPPS, nullptr}, + {X86_INS_RET, &Capstone2LlvmIrTranslatorX86_impl::translateRet}, + {X86_INS_ENCLS, nullptr}, + {X86_INS_ENCLU, nullptr}, + {X86_INS_ENTER, &Capstone2LlvmIrTranslatorX86_impl::translateEnter}, + {X86_INS_EXTRACTPS, nullptr}, + {X86_INS_EXTRQ, nullptr}, + {X86_INS_F2XM1, &Capstone2LlvmIrTranslatorX86_impl::translateF2xm1}, + {X86_INS_LCALL, &Capstone2LlvmIrTranslatorX86_impl::translateLcall}, + {X86_INS_LJMP, &Capstone2LlvmIrTranslatorX86_impl::translateLjmp}, + {X86_INS_FBLD, &Capstone2LlvmIrTranslatorX86_impl::translateFbld}, + {X86_INS_FBSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFbstp}, + {X86_INS_FCOMPP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FDECSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFdecstp}, + {X86_INS_FEMMS, nullptr}, + {X86_INS_FFREE, &Capstone2LlvmIrTranslatorX86_impl::translateFfree}, + {X86_INS_FICOM, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FICOMP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FINCSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFincstp}, + {X86_INS_FLDCW, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_FLDENV, &Capstone2LlvmIrTranslatorX86_impl::translatePseudoAsmFncOp0}, + {X86_INS_FLDL2E, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FLDL2T, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FLDLG2, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FLDLN2, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FLDPI, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FNCLEX, &Capstone2LlvmIrTranslatorX86_impl::translateFnclex}, + {X86_INS_FNINIT, &Capstone2LlvmIrTranslatorX86_impl::translateFninit}, + {X86_INS_FNOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_FNSTCW, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_FNSTSW, &Capstone2LlvmIrTranslatorX86_impl::translateFnstsw}, + {X86_INS_FPATAN, &Capstone2LlvmIrTranslatorX86_impl::translateFatan}, + {X86_INS_FPREM, &Capstone2LlvmIrTranslatorX86_impl::translateFprem}, + {X86_INS_FPREM1, &Capstone2LlvmIrTranslatorX86_impl::translateFprem}, + {X86_INS_FPTAN, &Capstone2LlvmIrTranslatorX86_impl::translateFtan}, + {X86_INS_FFREEP, nullptr}, + {X86_INS_FRNDINT, &Capstone2LlvmIrTranslatorX86_impl::translateFrndint}, + {X86_INS_FRSTOR, &Capstone2LlvmIrTranslatorX86_impl::translateFrstor}, + {X86_INS_FNSAVE, &Capstone2LlvmIrTranslatorX86_impl::translateFnsave}, + {X86_INS_FSCALE, &Capstone2LlvmIrTranslatorX86_impl::translateFscale}, + {X86_INS_FSETPM, nullptr}, + {X86_INS_FSINCOS, &Capstone2LlvmIrTranslatorX86_impl::translateFsincos}, + {X86_INS_FNSTENV, &Capstone2LlvmIrTranslatorX86_impl::translateFnstenv}, + {X86_INS_FXAM, &Capstone2LlvmIrTranslatorX86_impl::translateFxam}, + {X86_INS_FXRSTOR, &Capstone2LlvmIrTranslatorX86_impl::translateFxstor}, + {X86_INS_FXRSTOR64, &Capstone2LlvmIrTranslatorX86_impl::translateFxstor}, + {X86_INS_FXSAVE, &Capstone2LlvmIrTranslatorX86_impl::translateFxsave}, + {X86_INS_FXSAVE64, &Capstone2LlvmIrTranslatorX86_impl::translateFxsave}, + {X86_INS_FXTRACT, &Capstone2LlvmIrTranslatorX86_impl::translateFxtract}, + {X86_INS_FYL2X, &Capstone2LlvmIrTranslatorX86_impl::translateFyl2x}, + {X86_INS_FYL2XP1, &Capstone2LlvmIrTranslatorX86_impl::translateFyl2x}, + {X86_INS_MOVAPD, nullptr}, + {X86_INS_MOVAPS, nullptr}, + {X86_INS_ORPD, nullptr}, + {X86_INS_ORPS, nullptr}, + {X86_INS_VMOVAPD, nullptr}, + {X86_INS_VMOVAPS, nullptr}, + {X86_INS_XORPD, nullptr}, + {X86_INS_XORPS, nullptr}, + {X86_INS_GETSEC, nullptr}, + {X86_INS_HADDPD, nullptr}, + {X86_INS_HADDPS, nullptr}, + {X86_INS_HLT, nullptr}, + {X86_INS_HSUBPD, nullptr}, + {X86_INS_HSUBPS, nullptr}, + {X86_INS_IDIV, &Capstone2LlvmIrTranslatorX86_impl::translateDiv}, + {X86_INS_FILD, &Capstone2LlvmIrTranslatorX86_impl::translateFld}, + {X86_INS_IMUL, &Capstone2LlvmIrTranslatorX86_impl::translateImul}, + {X86_INS_IN, nullptr}, + {X86_INS_INC, &Capstone2LlvmIrTranslatorX86_impl::translateInc}, + {X86_INS_INSB, &Capstone2LlvmIrTranslatorX86_impl::translateIns}, + {X86_INS_INSERTPS, nullptr}, + {X86_INS_INSERTQ, nullptr}, + {X86_INS_INSD, &Capstone2LlvmIrTranslatorX86_impl::translateIns}, + {X86_INS_INSW, &Capstone2LlvmIrTranslatorX86_impl::translateIns}, + {X86_INS_INT, nullptr}, + {X86_INS_INT1, nullptr}, + {X86_INS_INT3, nullptr}, + {X86_INS_INTO, nullptr}, + {X86_INS_INVD, nullptr}, + {X86_INS_INVEPT, nullptr}, + {X86_INS_INVLPG, nullptr}, + {X86_INS_INVLPGA, nullptr}, + {X86_INS_INVPCID, nullptr}, + {X86_INS_INVVPID, nullptr}, + {X86_INS_IRET, nullptr}, + {X86_INS_IRETD, nullptr}, + {X86_INS_IRETQ, nullptr}, + {X86_INS_FISTTP, &Capstone2LlvmIrTranslatorX86_impl::translateFist}, + {X86_INS_FIST, &Capstone2LlvmIrTranslatorX86_impl::translateFist}, + {X86_INS_FISTP, &Capstone2LlvmIrTranslatorX86_impl::translateFist}, + {X86_INS_UCOMISD, nullptr}, + {X86_INS_UCOMISS, nullptr}, + {X86_INS_VCOMISD, nullptr}, + {X86_INS_VCOMISS, nullptr}, + {X86_INS_VCVTSD2SS, nullptr}, + {X86_INS_VCVTSI2SD, nullptr}, + {X86_INS_VCVTSI2SS, nullptr}, + {X86_INS_VCVTSS2SD, nullptr}, + {X86_INS_VCVTTSD2SI, nullptr}, + {X86_INS_VCVTTSD2USI, nullptr}, + {X86_INS_VCVTTSS2SI, nullptr}, + {X86_INS_VCVTTSS2USI, nullptr}, + {X86_INS_VCVTUSI2SD, nullptr}, + {X86_INS_VCVTUSI2SS, nullptr}, + {X86_INS_VUCOMISD, nullptr}, + {X86_INS_VUCOMISS, nullptr}, + {X86_INS_JAE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JA, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JBE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JB, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JCXZ, &Capstone2LlvmIrTranslatorX86_impl::translateJecxz}, + {X86_INS_JECXZ, &Capstone2LlvmIrTranslatorX86_impl::translateJecxz}, + {X86_INS_JE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JGE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JG, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JLE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JL, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JMP, &Capstone2LlvmIrTranslatorX86_impl::translateJmp}, + {X86_INS_JNE, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JNO, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JNP, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JNS, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JO, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JP, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_JRCXZ, &Capstone2LlvmIrTranslatorX86_impl::translateJecxz}, + {X86_INS_JS, &Capstone2LlvmIrTranslatorX86_impl::translateJCc}, + {X86_INS_KANDB, nullptr}, + {X86_INS_KANDD, nullptr}, + {X86_INS_KANDNB, nullptr}, + {X86_INS_KANDND, nullptr}, + {X86_INS_KANDNQ, nullptr}, + {X86_INS_KANDNW, nullptr}, + {X86_INS_KANDQ, nullptr}, + {X86_INS_KANDW, nullptr}, + {X86_INS_KMOVB, nullptr}, + {X86_INS_KMOVD, nullptr}, + {X86_INS_KMOVQ, nullptr}, + {X86_INS_KMOVW, nullptr}, + {X86_INS_KNOTB, nullptr}, + {X86_INS_KNOTD, nullptr}, + {X86_INS_KNOTQ, nullptr}, + {X86_INS_KNOTW, nullptr}, + {X86_INS_KORB, nullptr}, + {X86_INS_KORD, nullptr}, + {X86_INS_KORQ, nullptr}, + {X86_INS_KORTESTB, nullptr}, + {X86_INS_KORTESTD, nullptr}, + {X86_INS_KORTESTQ, nullptr}, + {X86_INS_KORTESTW, nullptr}, + {X86_INS_KORW, nullptr}, + {X86_INS_KSHIFTLB, nullptr}, + {X86_INS_KSHIFTLD, nullptr}, + {X86_INS_KSHIFTLQ, nullptr}, + {X86_INS_KSHIFTLW, nullptr}, + {X86_INS_KSHIFTRB, nullptr}, + {X86_INS_KSHIFTRD, nullptr}, + {X86_INS_KSHIFTRQ, nullptr}, + {X86_INS_KSHIFTRW, nullptr}, + {X86_INS_KUNPCKBW, nullptr}, + {X86_INS_KXNORB, nullptr}, + {X86_INS_KXNORD, nullptr}, + {X86_INS_KXNORQ, nullptr}, + {X86_INS_KXNORW, nullptr}, + {X86_INS_KXORB, nullptr}, + {X86_INS_KXORD, nullptr}, + {X86_INS_KXORQ, nullptr}, + {X86_INS_KXORW, nullptr}, + {X86_INS_LAHF, &Capstone2LlvmIrTranslatorX86_impl::translateLahf}, + {X86_INS_LAR, nullptr}, + {X86_INS_LDDQU, nullptr}, + {X86_INS_LDMXCSR, nullptr}, + {X86_INS_LDS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, + {X86_INS_FLDZ, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FLD1, &Capstone2LlvmIrTranslatorX86_impl::translateFloadConstant}, + {X86_INS_FLD, &Capstone2LlvmIrTranslatorX86_impl::translateFld}, + {X86_INS_LEA, &Capstone2LlvmIrTranslatorX86_impl::translateLea}, + {X86_INS_LEAVE, &Capstone2LlvmIrTranslatorX86_impl::translateLeave}, + {X86_INS_LES, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, + {X86_INS_LFENCE, nullptr}, + {X86_INS_LFS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, + {X86_INS_LGDT, nullptr}, + {X86_INS_LGS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, + {X86_INS_LIDT, nullptr}, + {X86_INS_LLDT, nullptr}, + {X86_INS_LMSW, nullptr}, + {X86_INS_OR, &Capstone2LlvmIrTranslatorX86_impl::translateOr}, + {X86_INS_SUB, &Capstone2LlvmIrTranslatorX86_impl::translateSub}, + {X86_INS_XOR, &Capstone2LlvmIrTranslatorX86_impl::translateXor}, + {X86_INS_LODSB, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, + {X86_INS_LODSD, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, + {X86_INS_LODSQ, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, + {X86_INS_LODSW, &Capstone2LlvmIrTranslatorX86_impl::translateLoadString}, + {X86_INS_LOOP, &Capstone2LlvmIrTranslatorX86_impl::translateLoop}, + {X86_INS_LOOPE, &Capstone2LlvmIrTranslatorX86_impl::translateLoop}, + {X86_INS_LOOPNE, &Capstone2LlvmIrTranslatorX86_impl::translateLoop}, + {X86_INS_RETF, &Capstone2LlvmIrTranslatorX86_impl::translateRet}, + {X86_INS_RETFQ, &Capstone2LlvmIrTranslatorX86_impl::translateRet}, + {X86_INS_LSL, nullptr}, + {X86_INS_LSS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr}, + {X86_INS_LTR, nullptr}, + {X86_INS_XADD, &Capstone2LlvmIrTranslatorX86_impl::translateAdd}, + {X86_INS_LZCNT, nullptr}, + {X86_INS_MASKMOVDQU, nullptr}, + {X86_INS_MAXPD, nullptr}, + {X86_INS_MAXPS, nullptr}, + {X86_INS_MAXSD, nullptr}, + {X86_INS_MAXSS, nullptr}, + {X86_INS_MFENCE, nullptr}, + {X86_INS_MINPD, nullptr}, + {X86_INS_MINPS, nullptr}, + {X86_INS_MINSD, nullptr}, + {X86_INS_MINSS, nullptr}, + {X86_INS_CVTPD2PI, nullptr}, + {X86_INS_CVTPI2PD, nullptr}, + {X86_INS_CVTPI2PS, nullptr}, + {X86_INS_CVTPS2PI, nullptr}, + {X86_INS_CVTTPD2PI, nullptr}, + {X86_INS_CVTTPS2PI, nullptr}, + {X86_INS_EMMS, nullptr}, + {X86_INS_MASKMOVQ, nullptr}, + {X86_INS_MOVD, nullptr}, + {X86_INS_MOVDQ2Q, nullptr}, + {X86_INS_MOVNTQ, nullptr}, + {X86_INS_MOVQ2DQ, nullptr}, + {X86_INS_MOVQ, nullptr}, + {X86_INS_PABSB, nullptr}, + {X86_INS_PABSD, nullptr}, + {X86_INS_PABSW, nullptr}, + {X86_INS_PACKSSDW, nullptr}, + {X86_INS_PACKSSWB, nullptr}, + {X86_INS_PACKUSWB, nullptr}, + {X86_INS_PADDB, nullptr}, + {X86_INS_PADDD, nullptr}, + {X86_INS_PADDQ, nullptr}, + {X86_INS_PADDSB, nullptr}, + {X86_INS_PADDSW, nullptr}, + {X86_INS_PADDUSB, nullptr}, + {X86_INS_PADDUSW, nullptr}, + {X86_INS_PADDW, nullptr}, + {X86_INS_PALIGNR, nullptr}, + {X86_INS_PANDN, nullptr}, + {X86_INS_PAND, nullptr}, + {X86_INS_PAVGB, nullptr}, + {X86_INS_PAVGW, nullptr}, + {X86_INS_PCMPEQB, nullptr}, + {X86_INS_PCMPEQD, nullptr}, + {X86_INS_PCMPEQW, nullptr}, + {X86_INS_PCMPGTB, nullptr}, + {X86_INS_PCMPGTD, nullptr}, + {X86_INS_PCMPGTW, nullptr}, + {X86_INS_PEXTRW, nullptr}, + {X86_INS_PHADDSW, nullptr}, + {X86_INS_PHADDW, nullptr}, + {X86_INS_PHADDD, nullptr}, + {X86_INS_PHSUBD, nullptr}, + {X86_INS_PHSUBSW, nullptr}, + {X86_INS_PHSUBW, nullptr}, + {X86_INS_PINSRW, nullptr}, + {X86_INS_PMADDUBSW, nullptr}, + {X86_INS_PMADDWD, nullptr}, + {X86_INS_PMAXSW, nullptr}, + {X86_INS_PMAXUB, nullptr}, + {X86_INS_PMINSW, nullptr}, + {X86_INS_PMINUB, nullptr}, + {X86_INS_PMOVMSKB, nullptr}, + {X86_INS_PMULHRSW, nullptr}, + {X86_INS_PMULHUW, nullptr}, + {X86_INS_PMULHW, nullptr}, + {X86_INS_PMULLW, nullptr}, + {X86_INS_PMULUDQ, nullptr}, + {X86_INS_POR, nullptr}, + {X86_INS_PSADBW, nullptr}, + {X86_INS_PSHUFB, nullptr}, + {X86_INS_PSHUFW, nullptr}, + {X86_INS_PSIGNB, nullptr}, + {X86_INS_PSIGND, nullptr}, + {X86_INS_PSIGNW, nullptr}, + {X86_INS_PSLLD, nullptr}, + {X86_INS_PSLLQ, nullptr}, + {X86_INS_PSLLW, nullptr}, + {X86_INS_PSRAD, nullptr}, + {X86_INS_PSRAW, nullptr}, + {X86_INS_PSRLD, nullptr}, + {X86_INS_PSRLQ, nullptr}, + {X86_INS_PSRLW, nullptr}, + {X86_INS_PSUBB, nullptr}, + {X86_INS_PSUBD, nullptr}, + {X86_INS_PSUBQ, nullptr}, + {X86_INS_PSUBSB, nullptr}, + {X86_INS_PSUBSW, nullptr}, + {X86_INS_PSUBUSB, nullptr}, + {X86_INS_PSUBUSW, nullptr}, + {X86_INS_PSUBW, nullptr}, + {X86_INS_PUNPCKHBW, nullptr}, + {X86_INS_PUNPCKHDQ, nullptr}, + {X86_INS_PUNPCKHWD, nullptr}, + {X86_INS_PUNPCKLBW, nullptr}, + {X86_INS_PUNPCKLDQ, nullptr}, + {X86_INS_PUNPCKLWD, nullptr}, + {X86_INS_PXOR, nullptr}, + {X86_INS_MONITOR, nullptr}, + {X86_INS_MONTMUL, nullptr}, + {X86_INS_MOV, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, + {X86_INS_MOVABS, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, + {X86_INS_MOVBE, nullptr}, + {X86_INS_MOVDDUP, nullptr}, + {X86_INS_MOVDQA, nullptr}, + {X86_INS_MOVDQU, nullptr}, + {X86_INS_MOVHLPS, nullptr}, + {X86_INS_MOVHPD, nullptr}, + {X86_INS_MOVHPS, nullptr}, + {X86_INS_MOVLHPS, nullptr}, + {X86_INS_MOVLPD, nullptr}, + {X86_INS_MOVLPS, nullptr}, + {X86_INS_MOVMSKPD, nullptr}, + {X86_INS_MOVMSKPS, nullptr}, + {X86_INS_MOVNTDQA, nullptr}, + {X86_INS_MOVNTDQ, nullptr}, + {X86_INS_MOVNTI, nullptr}, + {X86_INS_MOVNTPD, nullptr}, + {X86_INS_MOVNTPS, nullptr}, + {X86_INS_MOVNTSD, nullptr}, + {X86_INS_MOVNTSS, nullptr}, + {X86_INS_MOVSB, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, + {X86_INS_MOVSD, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, + {X86_INS_MOVSHDUP, nullptr}, + {X86_INS_MOVSLDUP, nullptr}, + {X86_INS_MOVSQ, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, + {X86_INS_MOVSS, nullptr}, + {X86_INS_MOVSW, &Capstone2LlvmIrTranslatorX86_impl::translateMoveString}, + {X86_INS_MOVSX, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, + {X86_INS_MOVSXD, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, + {X86_INS_MOVUPD, nullptr}, + {X86_INS_MOVUPS, nullptr}, + {X86_INS_MOVZX, &Capstone2LlvmIrTranslatorX86_impl::translateMov}, + {X86_INS_MPSADBW, nullptr}, + {X86_INS_MUL, &Capstone2LlvmIrTranslatorX86_impl::translateMul}, + {X86_INS_MULPD, nullptr}, + {X86_INS_MULPS, nullptr}, + {X86_INS_MULSD, nullptr}, + {X86_INS_MULSS, nullptr}, + {X86_INS_MULX, nullptr}, + {X86_INS_FMUL, &Capstone2LlvmIrTranslatorX86_impl::translateFmul}, + {X86_INS_FIMUL, &Capstone2LlvmIrTranslatorX86_impl::translateFmul}, + {X86_INS_FMULP, &Capstone2LlvmIrTranslatorX86_impl::translateFmul}, + {X86_INS_MWAIT, nullptr}, + {X86_INS_NEG, &Capstone2LlvmIrTranslatorX86_impl::translateNeg}, + {X86_INS_NOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_NOT, &Capstone2LlvmIrTranslatorX86_impl::translateNot}, + {X86_INS_OUT, nullptr}, + {X86_INS_OUTSB, &Capstone2LlvmIrTranslatorX86_impl::translateOuts}, + {X86_INS_OUTSD, &Capstone2LlvmIrTranslatorX86_impl::translateOuts}, + {X86_INS_OUTSW, &Capstone2LlvmIrTranslatorX86_impl::translateOuts}, + {X86_INS_PACKUSDW, nullptr}, + {X86_INS_PAUSE, nullptr}, + {X86_INS_PAVGUSB, nullptr}, + {X86_INS_PBLENDVB, nullptr}, + {X86_INS_PBLENDW, nullptr}, + {X86_INS_PCLMULQDQ, nullptr}, + {X86_INS_PCMPEQQ, nullptr}, + {X86_INS_PCMPESTRI, nullptr}, + {X86_INS_PCMPESTRM, nullptr}, + {X86_INS_PCMPGTQ, nullptr}, + {X86_INS_PCMPISTRI, nullptr}, + {X86_INS_PCMPISTRM, nullptr}, + {X86_INS_PDEP, nullptr}, + {X86_INS_PEXT, nullptr}, + {X86_INS_PEXTRB, nullptr}, + {X86_INS_PEXTRD, nullptr}, + {X86_INS_PEXTRQ, nullptr}, + {X86_INS_PF2ID, nullptr}, + {X86_INS_PF2IW, nullptr}, + {X86_INS_PFACC, nullptr}, + {X86_INS_PFADD, nullptr}, + {X86_INS_PFCMPEQ, nullptr}, + {X86_INS_PFCMPGE, nullptr}, + {X86_INS_PFCMPGT, nullptr}, + {X86_INS_PFMAX, nullptr}, + {X86_INS_PFMIN, nullptr}, + {X86_INS_PFMUL, nullptr}, + {X86_INS_PFNACC, nullptr}, + {X86_INS_PFPNACC, nullptr}, + {X86_INS_PFRCPIT1, nullptr}, + {X86_INS_PFRCPIT2, nullptr}, + {X86_INS_PFRCP, nullptr}, + {X86_INS_PFRSQIT1, nullptr}, + {X86_INS_PFRSQRT, nullptr}, + {X86_INS_PFSUBR, nullptr}, + {X86_INS_PFSUB, nullptr}, + {X86_INS_PHMINPOSUW, nullptr}, + {X86_INS_PI2FD, nullptr}, + {X86_INS_PI2FW, nullptr}, + {X86_INS_PINSRB, nullptr}, + {X86_INS_PINSRD, nullptr}, + {X86_INS_PINSRQ, nullptr}, + {X86_INS_PMAXSB, nullptr}, + {X86_INS_PMAXSD, nullptr}, + {X86_INS_PMAXUD, nullptr}, + {X86_INS_PMAXUW, nullptr}, + {X86_INS_PMINSB, nullptr}, + {X86_INS_PMINSD, nullptr}, + {X86_INS_PMINUD, nullptr}, + {X86_INS_PMINUW, nullptr}, + {X86_INS_PMOVSXBD, nullptr}, + {X86_INS_PMOVSXBQ, nullptr}, + {X86_INS_PMOVSXBW, nullptr}, + {X86_INS_PMOVSXDQ, nullptr}, + {X86_INS_PMOVSXWD, nullptr}, + {X86_INS_PMOVSXWQ, nullptr}, + {X86_INS_PMOVZXBD, nullptr}, + {X86_INS_PMOVZXBQ, nullptr}, + {X86_INS_PMOVZXBW, nullptr}, + {X86_INS_PMOVZXDQ, nullptr}, + {X86_INS_PMOVZXWD, nullptr}, + {X86_INS_PMOVZXWQ, nullptr}, + {X86_INS_PMULDQ, nullptr}, + {X86_INS_PMULHRW, nullptr}, + {X86_INS_PMULLD, nullptr}, + {X86_INS_POP, &Capstone2LlvmIrTranslatorX86_impl::translatePop}, + {X86_INS_POPAW, &Capstone2LlvmIrTranslatorX86_impl::translatePopa}, // X86_INS_POPAW == POPA + {X86_INS_POPAL, &Capstone2LlvmIrTranslatorX86_impl::translatePopa}, // X86_INS_POPAL == POPAD + {X86_INS_POPCNT, nullptr}, + {X86_INS_POPF, &Capstone2LlvmIrTranslatorX86_impl::translatePopEflags}, + {X86_INS_POPFD, &Capstone2LlvmIrTranslatorX86_impl::translatePopEflags}, + {X86_INS_POPFQ, &Capstone2LlvmIrTranslatorX86_impl::translatePopEflags}, + {X86_INS_PREFETCH, nullptr}, + {X86_INS_PREFETCHNTA, nullptr}, + {X86_INS_PREFETCHT0, nullptr}, + {X86_INS_PREFETCHT1, nullptr}, + {X86_INS_PREFETCHT2, nullptr}, + {X86_INS_PREFETCHW, nullptr}, + {X86_INS_PSHUFD, nullptr}, + {X86_INS_PSHUFHW, nullptr}, + {X86_INS_PSHUFLW, nullptr}, + {X86_INS_PSLLDQ, nullptr}, + {X86_INS_PSRLDQ, nullptr}, + {X86_INS_PSWAPD, nullptr}, + {X86_INS_PTEST, nullptr}, + {X86_INS_PUNPCKHQDQ, nullptr}, + {X86_INS_PUNPCKLQDQ, nullptr}, + {X86_INS_PUSH, &Capstone2LlvmIrTranslatorX86_impl::translatePush}, + {X86_INS_PUSHAW, &Capstone2LlvmIrTranslatorX86_impl::translatePusha}, // X86_INS_PUSHAW = PUSHA + {X86_INS_PUSHAL, &Capstone2LlvmIrTranslatorX86_impl::translatePusha}, // X86_INS_PUSHAL = PUSHAD + {X86_INS_PUSHF, &Capstone2LlvmIrTranslatorX86_impl::translatePushEflags}, + {X86_INS_PUSHFD, &Capstone2LlvmIrTranslatorX86_impl::translatePushEflags}, + {X86_INS_PUSHFQ, &Capstone2LlvmIrTranslatorX86_impl::translatePushEflags}, + {X86_INS_RCL, &Capstone2LlvmIrTranslatorX86_impl::translateRcl}, + {X86_INS_RCPPS, nullptr}, + {X86_INS_RCPSS, nullptr}, + {X86_INS_RCR, &Capstone2LlvmIrTranslatorX86_impl::translateRcr}, + {X86_INS_RDFSBASE, nullptr}, + {X86_INS_RDGSBASE, nullptr}, + {X86_INS_RDMSR, nullptr}, + {X86_INS_RDPMC, nullptr}, + {X86_INS_RDRAND, nullptr}, + {X86_INS_RDSEED, nullptr}, + {X86_INS_RDTSC, &Capstone2LlvmIrTranslatorX86_impl::translateRdtsc}, + {X86_INS_RDTSCP, &Capstone2LlvmIrTranslatorX86_impl::translateRdtscp}, + {X86_INS_ROL, &Capstone2LlvmIrTranslatorX86_impl::translateRol}, + {X86_INS_ROR, &Capstone2LlvmIrTranslatorX86_impl::translateRor}, + {X86_INS_RORX, nullptr}, + {X86_INS_ROUNDPD, nullptr}, + {X86_INS_ROUNDPS, nullptr}, + {X86_INS_ROUNDSD, nullptr}, + {X86_INS_ROUNDSS, nullptr}, + {X86_INS_RSM, nullptr}, + {X86_INS_RSQRTPS, nullptr}, + {X86_INS_RSQRTSS, nullptr}, + {X86_INS_SAHF, &Capstone2LlvmIrTranslatorX86_impl::translateSahf}, + {X86_INS_SAL, &Capstone2LlvmIrTranslatorX86_impl::translateShiftLeft}, + {X86_INS_SALC, &Capstone2LlvmIrTranslatorX86_impl::translateSalc}, + {X86_INS_SAR, &Capstone2LlvmIrTranslatorX86_impl::translateShiftRight}, + {X86_INS_SARX, nullptr}, + {X86_INS_SBB, &Capstone2LlvmIrTranslatorX86_impl::translateSbb}, + {X86_INS_SCASB, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, + {X86_INS_SCASD, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, + {X86_INS_SCASQ, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, + {X86_INS_SCASW, &Capstone2LlvmIrTranslatorX86_impl::translateScanString}, + {X86_INS_SETAE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETA, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETBE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETB, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETGE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETG, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETLE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETL, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETNE, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETNO, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETNP, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETNS, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETO, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETP, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SETS, &Capstone2LlvmIrTranslatorX86_impl::translateSetCc}, + {X86_INS_SFENCE, nullptr}, + {X86_INS_SGDT, nullptr}, + {X86_INS_SHA1MSG1, nullptr}, + {X86_INS_SHA1MSG2, nullptr}, + {X86_INS_SHA1NEXTE, nullptr}, + {X86_INS_SHA1RNDS4, nullptr}, + {X86_INS_SHA256MSG1, nullptr}, + {X86_INS_SHA256MSG2, nullptr}, + {X86_INS_SHA256RNDS2, nullptr}, + {X86_INS_SHL, &Capstone2LlvmIrTranslatorX86_impl::translateShiftLeft}, + {X86_INS_SHLD, &Capstone2LlvmIrTranslatorX86_impl::translateShld}, + {X86_INS_SHLX, nullptr}, + {X86_INS_SHR, &Capstone2LlvmIrTranslatorX86_impl::translateShiftRight}, + {X86_INS_SHRD, &Capstone2LlvmIrTranslatorX86_impl::translateShrd}, + {X86_INS_SHRX, nullptr}, + {X86_INS_SHUFPD, nullptr}, + {X86_INS_SHUFPS, nullptr}, + {X86_INS_SIDT, nullptr}, + {X86_INS_FSIN, &Capstone2LlvmIrTranslatorX86_impl::translateFsin}, + {X86_INS_SKINIT, nullptr}, + {X86_INS_SLDT, nullptr}, + {X86_INS_SMSW, nullptr}, + {X86_INS_SQRTPD, nullptr}, + {X86_INS_SQRTPS, nullptr}, + {X86_INS_SQRTSD, nullptr}, + {X86_INS_SQRTSS, nullptr}, + {X86_INS_FSQRT, &Capstone2LlvmIrTranslatorX86_impl::translateFsqrt}, + {X86_INS_STAC, nullptr}, + {X86_INS_STC, &Capstone2LlvmIrTranslatorX86_impl::translateStc}, + {X86_INS_STD, &Capstone2LlvmIrTranslatorX86_impl::translateStd}, + {X86_INS_STGI, nullptr}, + {X86_INS_STI, nullptr}, + {X86_INS_STMXCSR, nullptr}, + {X86_INS_STOSB, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, + {X86_INS_STOSD, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, + {X86_INS_STOSQ, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, + {X86_INS_STOSW, &Capstone2LlvmIrTranslatorX86_impl::translateStoreString}, + {X86_INS_STR, nullptr}, + {X86_INS_FST, &Capstone2LlvmIrTranslatorX86_impl::translateFst}, + {X86_INS_FSTP, &Capstone2LlvmIrTranslatorX86_impl::translateFst}, + {X86_INS_FSTPNCE, nullptr}, + {X86_INS_FXCH, &Capstone2LlvmIrTranslatorX86_impl::translateFxch}, + {X86_INS_SUBPD, nullptr}, + {X86_INS_SUBPS, nullptr}, + {X86_INS_FSUBR, &Capstone2LlvmIrTranslatorX86_impl::translateFsubr}, + {X86_INS_FISUBR, &Capstone2LlvmIrTranslatorX86_impl::translateFsubr}, + {X86_INS_FSUBRP, &Capstone2LlvmIrTranslatorX86_impl::translateFsubr}, + {X86_INS_SUBSD, nullptr}, + {X86_INS_SUBSS, nullptr}, + {X86_INS_FSUB, &Capstone2LlvmIrTranslatorX86_impl::translateFsub}, + {X86_INS_FISUB, &Capstone2LlvmIrTranslatorX86_impl::translateFsub}, + {X86_INS_FSUBP, &Capstone2LlvmIrTranslatorX86_impl::translateFsub}, + {X86_INS_SWAPGS, nullptr}, + {X86_INS_SYSCALL, nullptr}, + {X86_INS_SYSENTER, nullptr}, + {X86_INS_SYSEXIT, nullptr}, + {X86_INS_SYSRET, nullptr}, + {X86_INS_T1MSKC, nullptr}, + {X86_INS_TEST, &Capstone2LlvmIrTranslatorX86_impl::translateAnd}, + {X86_INS_UD2, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_FTST, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_TZCNT, nullptr}, + {X86_INS_TZMSK, nullptr}, + {X86_INS_FUCOMPI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FUCOMI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FUCOMPP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FUCOMP, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_FUCOM, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop}, + {X86_INS_UD1, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_UNPCKHPD, nullptr}, + {X86_INS_UNPCKHPS, nullptr}, + {X86_INS_UNPCKLPD, nullptr}, + {X86_INS_UNPCKLPS, nullptr}, + {X86_INS_VADDPD, nullptr}, + {X86_INS_VADDPS, nullptr}, + {X86_INS_VADDSD, nullptr}, + {X86_INS_VADDSS, nullptr}, + {X86_INS_VADDSUBPD, nullptr}, + {X86_INS_VADDSUBPS, nullptr}, + {X86_INS_VAESDECLAST, nullptr}, + {X86_INS_VAESDEC, nullptr}, + {X86_INS_VAESENCLAST, nullptr}, + {X86_INS_VAESENC, nullptr}, + {X86_INS_VAESIMC, nullptr}, + {X86_INS_VAESKEYGENASSIST, nullptr}, + {X86_INS_VALIGND, nullptr}, + {X86_INS_VALIGNQ, nullptr}, + {X86_INS_VANDNPD, nullptr}, + {X86_INS_VANDNPS, nullptr}, + {X86_INS_VANDPD, nullptr}, + {X86_INS_VANDPS, nullptr}, + {X86_INS_VBLENDMPD, nullptr}, + {X86_INS_VBLENDMPS, nullptr}, + {X86_INS_VBLENDPD, nullptr}, + {X86_INS_VBLENDPS, nullptr}, + {X86_INS_VBLENDVPD, nullptr}, + {X86_INS_VBLENDVPS, nullptr}, + {X86_INS_VBROADCASTF128, nullptr}, + {X86_INS_VBROADCASTI32X4, nullptr}, + {X86_INS_VBROADCASTI64X4, nullptr}, + {X86_INS_VBROADCASTSD, nullptr}, + {X86_INS_VBROADCASTSS, nullptr}, + {X86_INS_VCOMPRESSPD, nullptr}, + {X86_INS_VCOMPRESSPS, nullptr}, + {X86_INS_VCVTDQ2PD, nullptr}, + {X86_INS_VCVTDQ2PS, nullptr}, + {X86_INS_VCVTPD2DQ, nullptr}, + {X86_INS_VCVTPD2PS, nullptr}, + {X86_INS_VCVTPD2UDQ, nullptr}, + {X86_INS_VCVTPH2PS, nullptr}, + {X86_INS_VCVTPS2DQ, nullptr}, + {X86_INS_VCVTPS2PD, nullptr}, + {X86_INS_VCVTPS2PH, nullptr}, + {X86_INS_VCVTPS2UDQ, nullptr}, + {X86_INS_VCVTSD2SI, nullptr}, + {X86_INS_VCVTSD2USI, nullptr}, + {X86_INS_VCVTSS2SI, nullptr}, + {X86_INS_VCVTSS2USI, nullptr}, + {X86_INS_VCVTTPD2DQ, nullptr}, + {X86_INS_VCVTTPD2UDQ, nullptr}, + {X86_INS_VCVTTPS2DQ, nullptr}, + {X86_INS_VCVTTPS2UDQ, nullptr}, + {X86_INS_VCVTUDQ2PD, nullptr}, + {X86_INS_VCVTUDQ2PS, nullptr}, + {X86_INS_VDIVPD, nullptr}, + {X86_INS_VDIVPS, nullptr}, + {X86_INS_VDIVSD, nullptr}, + {X86_INS_VDIVSS, nullptr}, + {X86_INS_VDPPD, nullptr}, + {X86_INS_VDPPS, nullptr}, + {X86_INS_VERR, nullptr}, + {X86_INS_VERW, nullptr}, + {X86_INS_VEXP2PD, nullptr}, + {X86_INS_VEXP2PS, nullptr}, + {X86_INS_VEXPANDPD, nullptr}, + {X86_INS_VEXPANDPS, nullptr}, + {X86_INS_VEXTRACTF128, nullptr}, + {X86_INS_VEXTRACTF32X4, nullptr}, + {X86_INS_VEXTRACTF64X4, nullptr}, + {X86_INS_VEXTRACTI128, nullptr}, + {X86_INS_VEXTRACTI32X4, nullptr}, + {X86_INS_VEXTRACTI64X4, nullptr}, + {X86_INS_VEXTRACTPS, nullptr}, + {X86_INS_VFMADD132PD, nullptr}, + {X86_INS_VFMADD132PS, nullptr}, + {X86_INS_VFMADDPD, nullptr}, + {X86_INS_VFMADD213PD, nullptr}, + {X86_INS_VFMADD231PD, nullptr}, + {X86_INS_VFMADDPS, nullptr}, + {X86_INS_VFMADD213PS, nullptr}, + {X86_INS_VFMADD231PS, nullptr}, + {X86_INS_VFMADDSD, nullptr}, + {X86_INS_VFMADD213SD, nullptr}, + {X86_INS_VFMADD132SD, nullptr}, + {X86_INS_VFMADD231SD, nullptr}, + {X86_INS_VFMADDSS, nullptr}, + {X86_INS_VFMADD213SS, nullptr}, + {X86_INS_VFMADD132SS, nullptr}, + {X86_INS_VFMADD231SS, nullptr}, + {X86_INS_VFMADDSUB132PD, nullptr}, + {X86_INS_VFMADDSUB132PS, nullptr}, + {X86_INS_VFMADDSUBPD, nullptr}, + {X86_INS_VFMADDSUB213PD, nullptr}, + {X86_INS_VFMADDSUB231PD, nullptr}, + {X86_INS_VFMADDSUBPS, nullptr}, + {X86_INS_VFMADDSUB213PS, nullptr}, + {X86_INS_VFMADDSUB231PS, nullptr}, + {X86_INS_VFMSUB132PD, nullptr}, + {X86_INS_VFMSUB132PS, nullptr}, + {X86_INS_VFMSUBADD132PD, nullptr}, + {X86_INS_VFMSUBADD132PS, nullptr}, + {X86_INS_VFMSUBADDPD, nullptr}, + {X86_INS_VFMSUBADD213PD, nullptr}, + {X86_INS_VFMSUBADD231PD, nullptr}, + {X86_INS_VFMSUBADDPS, nullptr}, + {X86_INS_VFMSUBADD213PS, nullptr}, + {X86_INS_VFMSUBADD231PS, nullptr}, + {X86_INS_VFMSUBPD, nullptr}, + {X86_INS_VFMSUB213PD, nullptr}, + {X86_INS_VFMSUB231PD, nullptr}, + {X86_INS_VFMSUBPS, nullptr}, + {X86_INS_VFMSUB213PS, nullptr}, + {X86_INS_VFMSUB231PS, nullptr}, + {X86_INS_VFMSUBSD, nullptr}, + {X86_INS_VFMSUB213SD, nullptr}, + {X86_INS_VFMSUB132SD, nullptr}, + {X86_INS_VFMSUB231SD, nullptr}, + {X86_INS_VFMSUBSS, nullptr}, + {X86_INS_VFMSUB213SS, nullptr}, + {X86_INS_VFMSUB132SS, nullptr}, + {X86_INS_VFMSUB231SS, nullptr}, + {X86_INS_VFNMADD132PD, nullptr}, + {X86_INS_VFNMADD132PS, nullptr}, + {X86_INS_VFNMADDPD, nullptr}, + {X86_INS_VFNMADD213PD, nullptr}, + {X86_INS_VFNMADD231PD, nullptr}, + {X86_INS_VFNMADDPS, nullptr}, + {X86_INS_VFNMADD213PS, nullptr}, + {X86_INS_VFNMADD231PS, nullptr}, + {X86_INS_VFNMADDSD, nullptr}, + {X86_INS_VFNMADD213SD, nullptr}, + {X86_INS_VFNMADD132SD, nullptr}, + {X86_INS_VFNMADD231SD, nullptr}, + {X86_INS_VFNMADDSS, nullptr}, + {X86_INS_VFNMADD213SS, nullptr}, + {X86_INS_VFNMADD132SS, nullptr}, + {X86_INS_VFNMADD231SS, nullptr}, + {X86_INS_VFNMSUB132PD, nullptr}, + {X86_INS_VFNMSUB132PS, nullptr}, + {X86_INS_VFNMSUBPD, nullptr}, + {X86_INS_VFNMSUB213PD, nullptr}, + {X86_INS_VFNMSUB231PD, nullptr}, + {X86_INS_VFNMSUBPS, nullptr}, + {X86_INS_VFNMSUB213PS, nullptr}, + {X86_INS_VFNMSUB231PS, nullptr}, + {X86_INS_VFNMSUBSD, nullptr}, + {X86_INS_VFNMSUB213SD, nullptr}, + {X86_INS_VFNMSUB132SD, nullptr}, + {X86_INS_VFNMSUB231SD, nullptr}, + {X86_INS_VFNMSUBSS, nullptr}, + {X86_INS_VFNMSUB213SS, nullptr}, + {X86_INS_VFNMSUB132SS, nullptr}, + {X86_INS_VFNMSUB231SS, nullptr}, + {X86_INS_VFRCZPD, nullptr}, + {X86_INS_VFRCZPS, nullptr}, + {X86_INS_VFRCZSD, nullptr}, + {X86_INS_VFRCZSS, nullptr}, + {X86_INS_VORPD, nullptr}, + {X86_INS_VORPS, nullptr}, + {X86_INS_VXORPD, nullptr}, + {X86_INS_VXORPS, nullptr}, + {X86_INS_VGATHERDPD, nullptr}, + {X86_INS_VGATHERDPS, nullptr}, + {X86_INS_VGATHERPF0DPD, nullptr}, + {X86_INS_VGATHERPF0DPS, nullptr}, + {X86_INS_VGATHERPF0QPD, nullptr}, + {X86_INS_VGATHERPF0QPS, nullptr}, + {X86_INS_VGATHERPF1DPD, nullptr}, + {X86_INS_VGATHERPF1DPS, nullptr}, + {X86_INS_VGATHERPF1QPD, nullptr}, + {X86_INS_VGATHERPF1QPS, nullptr}, + {X86_INS_VGATHERQPD, nullptr}, + {X86_INS_VGATHERQPS, nullptr}, + {X86_INS_VHADDPD, nullptr}, + {X86_INS_VHADDPS, nullptr}, + {X86_INS_VHSUBPD, nullptr}, + {X86_INS_VHSUBPS, nullptr}, + {X86_INS_VINSERTF128, nullptr}, + {X86_INS_VINSERTF32X4, nullptr}, + {X86_INS_VINSERTF32X8, nullptr}, + {X86_INS_VINSERTF64X2, nullptr}, + {X86_INS_VINSERTF64X4, nullptr}, + {X86_INS_VINSERTI128, nullptr}, + {X86_INS_VINSERTI32X4, nullptr}, + {X86_INS_VINSERTI32X8, nullptr}, + {X86_INS_VINSERTI64X2, nullptr}, + {X86_INS_VINSERTI64X4, nullptr}, + {X86_INS_VINSERTPS, nullptr}, + {X86_INS_VLDDQU, nullptr}, + {X86_INS_VLDMXCSR, nullptr}, + {X86_INS_VMASKMOVDQU, nullptr}, + {X86_INS_VMASKMOVPD, nullptr}, + {X86_INS_VMASKMOVPS, nullptr}, + {X86_INS_VMAXPD, nullptr}, + {X86_INS_VMAXPS, nullptr}, + {X86_INS_VMAXSD, nullptr}, + {X86_INS_VMAXSS, nullptr}, + {X86_INS_VMCALL, nullptr}, + {X86_INS_VMCLEAR, nullptr}, + {X86_INS_VMFUNC, nullptr}, + {X86_INS_VMINPD, nullptr}, + {X86_INS_VMINPS, nullptr}, + {X86_INS_VMINSD, nullptr}, + {X86_INS_VMINSS, nullptr}, + {X86_INS_VMLAUNCH, nullptr}, + {X86_INS_VMLOAD, nullptr}, + {X86_INS_VMMCALL, nullptr}, + {X86_INS_VMOVQ, nullptr}, + {X86_INS_VMOVDDUP, nullptr}, + {X86_INS_VMOVD, nullptr}, + {X86_INS_VMOVDQA32, nullptr}, + {X86_INS_VMOVDQA64, nullptr}, + {X86_INS_VMOVDQA, nullptr}, + {X86_INS_VMOVDQU16, nullptr}, + {X86_INS_VMOVDQU32, nullptr}, + {X86_INS_VMOVDQU64, nullptr}, + {X86_INS_VMOVDQU8, nullptr}, + {X86_INS_VMOVDQU, nullptr}, + {X86_INS_VMOVHLPS, nullptr}, + {X86_INS_VMOVHPD, nullptr}, + {X86_INS_VMOVHPS, nullptr}, + {X86_INS_VMOVLHPS, nullptr}, + {X86_INS_VMOVLPD, nullptr}, + {X86_INS_VMOVLPS, nullptr}, + {X86_INS_VMOVMSKPD, nullptr}, + {X86_INS_VMOVMSKPS, nullptr}, + {X86_INS_VMOVNTDQA, nullptr}, + {X86_INS_VMOVNTDQ, nullptr}, + {X86_INS_VMOVNTPD, nullptr}, + {X86_INS_VMOVNTPS, nullptr}, + {X86_INS_VMOVSD, nullptr}, + {X86_INS_VMOVSHDUP, nullptr}, + {X86_INS_VMOVSLDUP, nullptr}, + {X86_INS_VMOVSS, nullptr}, + {X86_INS_VMOVUPD, nullptr}, + {X86_INS_VMOVUPS, nullptr}, + {X86_INS_VMPSADBW, nullptr}, + {X86_INS_VMPTRLD, nullptr}, + {X86_INS_VMPTRST, nullptr}, + {X86_INS_VMREAD, nullptr}, + {X86_INS_VMRESUME, nullptr}, + {X86_INS_VMRUN, nullptr}, + {X86_INS_VMSAVE, nullptr}, + {X86_INS_VMULPD, nullptr}, + {X86_INS_VMULPS, nullptr}, + {X86_INS_VMULSD, nullptr}, + {X86_INS_VMULSS, nullptr}, + {X86_INS_VMWRITE, nullptr}, + {X86_INS_VMXOFF, nullptr}, + {X86_INS_VMXON, nullptr}, + {X86_INS_VPABSB, nullptr}, + {X86_INS_VPABSD, nullptr}, + {X86_INS_VPABSQ, nullptr}, + {X86_INS_VPABSW, nullptr}, + {X86_INS_VPACKSSDW, nullptr}, + {X86_INS_VPACKSSWB, nullptr}, + {X86_INS_VPACKUSDW, nullptr}, + {X86_INS_VPACKUSWB, nullptr}, + {X86_INS_VPADDB, nullptr}, + {X86_INS_VPADDD, nullptr}, + {X86_INS_VPADDQ, nullptr}, + {X86_INS_VPADDSB, nullptr}, + {X86_INS_VPADDSW, nullptr}, + {X86_INS_VPADDUSB, nullptr}, + {X86_INS_VPADDUSW, nullptr}, + {X86_INS_VPADDW, nullptr}, + {X86_INS_VPALIGNR, nullptr}, + {X86_INS_VPANDD, nullptr}, + {X86_INS_VPANDND, nullptr}, + {X86_INS_VPANDNQ, nullptr}, + {X86_INS_VPANDN, nullptr}, + {X86_INS_VPANDQ, nullptr}, + {X86_INS_VPAND, nullptr}, + {X86_INS_VPAVGB, nullptr}, + {X86_INS_VPAVGW, nullptr}, + {X86_INS_VPBLENDD, nullptr}, + {X86_INS_VPBLENDMB, nullptr}, + {X86_INS_VPBLENDMD, nullptr}, + {X86_INS_VPBLENDMQ, nullptr}, + {X86_INS_VPBLENDMW, nullptr}, + {X86_INS_VPBLENDVB, nullptr}, + {X86_INS_VPBLENDW, nullptr}, + {X86_INS_VPBROADCASTB, nullptr}, + {X86_INS_VPBROADCASTD, nullptr}, + {X86_INS_VPBROADCASTMB2Q, nullptr}, + {X86_INS_VPBROADCASTMW2D, nullptr}, + {X86_INS_VPBROADCASTQ, nullptr}, + {X86_INS_VPBROADCASTW, nullptr}, + {X86_INS_VPCLMULQDQ, nullptr}, + {X86_INS_VPCMOV, nullptr}, + {X86_INS_VPCMPB, nullptr}, + {X86_INS_VPCMPD, nullptr}, + {X86_INS_VPCMPEQB, nullptr}, + {X86_INS_VPCMPEQD, nullptr}, + {X86_INS_VPCMPEQQ, nullptr}, + {X86_INS_VPCMPEQW, nullptr}, + {X86_INS_VPCMPESTRI, nullptr}, + {X86_INS_VPCMPESTRM, nullptr}, + {X86_INS_VPCMPGTB, nullptr}, + {X86_INS_VPCMPGTD, nullptr}, + {X86_INS_VPCMPGTQ, nullptr}, + {X86_INS_VPCMPGTW, nullptr}, + {X86_INS_VPCMPISTRI, nullptr}, + {X86_INS_VPCMPISTRM, nullptr}, + {X86_INS_VPCMPQ, nullptr}, + {X86_INS_VPCMPUB, nullptr}, + {X86_INS_VPCMPUD, nullptr}, + {X86_INS_VPCMPUQ, nullptr}, + {X86_INS_VPCMPUW, nullptr}, + {X86_INS_VPCMPW, nullptr}, + {X86_INS_VPCOMB, nullptr}, + {X86_INS_VPCOMD, nullptr}, + {X86_INS_VPCOMPRESSD, nullptr}, + {X86_INS_VPCOMPRESSQ, nullptr}, + {X86_INS_VPCOMQ, nullptr}, + {X86_INS_VPCOMUB, nullptr}, + {X86_INS_VPCOMUD, nullptr}, + {X86_INS_VPCOMUQ, nullptr}, + {X86_INS_VPCOMUW, nullptr}, + {X86_INS_VPCOMW, nullptr}, + {X86_INS_VPCONFLICTD, nullptr}, + {X86_INS_VPCONFLICTQ, nullptr}, + {X86_INS_VPERM2F128, nullptr}, + {X86_INS_VPERM2I128, nullptr}, + {X86_INS_VPERMD, nullptr}, + {X86_INS_VPERMI2D, nullptr}, + {X86_INS_VPERMI2PD, nullptr}, + {X86_INS_VPERMI2PS, nullptr}, + {X86_INS_VPERMI2Q, nullptr}, + {X86_INS_VPERMIL2PD, nullptr}, + {X86_INS_VPERMIL2PS, nullptr}, + {X86_INS_VPERMILPD, nullptr}, + {X86_INS_VPERMILPS, nullptr}, + {X86_INS_VPERMPD, nullptr}, + {X86_INS_VPERMPS, nullptr}, + {X86_INS_VPERMQ, nullptr}, + {X86_INS_VPERMT2D, nullptr}, + {X86_INS_VPERMT2PD, nullptr}, + {X86_INS_VPERMT2PS, nullptr}, + {X86_INS_VPERMT2Q, nullptr}, + {X86_INS_VPEXPANDD, nullptr}, + {X86_INS_VPEXPANDQ, nullptr}, + {X86_INS_VPEXTRB, nullptr}, + {X86_INS_VPEXTRD, nullptr}, + {X86_INS_VPEXTRQ, nullptr}, + {X86_INS_VPEXTRW, nullptr}, + {X86_INS_VPGATHERDD, nullptr}, + {X86_INS_VPGATHERDQ, nullptr}, + {X86_INS_VPGATHERQD, nullptr}, + {X86_INS_VPGATHERQQ, nullptr}, + {X86_INS_VPHADDBD, nullptr}, + {X86_INS_VPHADDBQ, nullptr}, + {X86_INS_VPHADDBW, nullptr}, + {X86_INS_VPHADDDQ, nullptr}, + {X86_INS_VPHADDD, nullptr}, + {X86_INS_VPHADDSW, nullptr}, + {X86_INS_VPHADDUBD, nullptr}, + {X86_INS_VPHADDUBQ, nullptr}, + {X86_INS_VPHADDUBW, nullptr}, + {X86_INS_VPHADDUDQ, nullptr}, + {X86_INS_VPHADDUWD, nullptr}, + {X86_INS_VPHADDUWQ, nullptr}, + {X86_INS_VPHADDWD, nullptr}, + {X86_INS_VPHADDWQ, nullptr}, + {X86_INS_VPHADDW, nullptr}, + {X86_INS_VPHMINPOSUW, nullptr}, + {X86_INS_VPHSUBBW, nullptr}, + {X86_INS_VPHSUBDQ, nullptr}, + {X86_INS_VPHSUBD, nullptr}, + {X86_INS_VPHSUBSW, nullptr}, + {X86_INS_VPHSUBWD, nullptr}, + {X86_INS_VPHSUBW, nullptr}, + {X86_INS_VPINSRB, nullptr}, + {X86_INS_VPINSRD, nullptr}, + {X86_INS_VPINSRQ, nullptr}, + {X86_INS_VPINSRW, nullptr}, + {X86_INS_VPLZCNTD, nullptr}, + {X86_INS_VPLZCNTQ, nullptr}, + {X86_INS_VPMACSDD, nullptr}, + {X86_INS_VPMACSDQH, nullptr}, + {X86_INS_VPMACSDQL, nullptr}, + {X86_INS_VPMACSSDD, nullptr}, + {X86_INS_VPMACSSDQH, nullptr}, + {X86_INS_VPMACSSDQL, nullptr}, + {X86_INS_VPMACSSWD, nullptr}, + {X86_INS_VPMACSSWW, nullptr}, + {X86_INS_VPMACSWD, nullptr}, + {X86_INS_VPMACSWW, nullptr}, + {X86_INS_VPMADCSSWD, nullptr}, + {X86_INS_VPMADCSWD, nullptr}, + {X86_INS_VPMADDUBSW, nullptr}, + {X86_INS_VPMADDWD, nullptr}, + {X86_INS_VPMASKMOVD, nullptr}, + {X86_INS_VPMASKMOVQ, nullptr}, + {X86_INS_VPMAXSB, nullptr}, + {X86_INS_VPMAXSD, nullptr}, + {X86_INS_VPMAXSQ, nullptr}, + {X86_INS_VPMAXSW, nullptr}, + {X86_INS_VPMAXUB, nullptr}, + {X86_INS_VPMAXUD, nullptr}, + {X86_INS_VPMAXUQ, nullptr}, + {X86_INS_VPMAXUW, nullptr}, + {X86_INS_VPMINSB, nullptr}, + {X86_INS_VPMINSD, nullptr}, + {X86_INS_VPMINSQ, nullptr}, + {X86_INS_VPMINSW, nullptr}, + {X86_INS_VPMINUB, nullptr}, + {X86_INS_VPMINUD, nullptr}, + {X86_INS_VPMINUQ, nullptr}, + {X86_INS_VPMINUW, nullptr}, + {X86_INS_VPMOVDB, nullptr}, + {X86_INS_VPMOVDW, nullptr}, + {X86_INS_VPMOVM2B, nullptr}, + {X86_INS_VPMOVM2D, nullptr}, + {X86_INS_VPMOVM2Q, nullptr}, + {X86_INS_VPMOVM2W, nullptr}, + {X86_INS_VPMOVMSKB, nullptr}, + {X86_INS_VPMOVQB, nullptr}, + {X86_INS_VPMOVQD, nullptr}, + {X86_INS_VPMOVQW, nullptr}, + {X86_INS_VPMOVSDB, nullptr}, + {X86_INS_VPMOVSDW, nullptr}, + {X86_INS_VPMOVSQB, nullptr}, + {X86_INS_VPMOVSQD, nullptr}, + {X86_INS_VPMOVSQW, nullptr}, + {X86_INS_VPMOVSXBD, nullptr}, + {X86_INS_VPMOVSXBQ, nullptr}, + {X86_INS_VPMOVSXBW, nullptr}, + {X86_INS_VPMOVSXDQ, nullptr}, + {X86_INS_VPMOVSXWD, nullptr}, + {X86_INS_VPMOVSXWQ, nullptr}, + {X86_INS_VPMOVUSDB, nullptr}, + {X86_INS_VPMOVUSDW, nullptr}, + {X86_INS_VPMOVUSQB, nullptr}, + {X86_INS_VPMOVUSQD, nullptr}, + {X86_INS_VPMOVUSQW, nullptr}, + {X86_INS_VPMOVZXBD, nullptr}, + {X86_INS_VPMOVZXBQ, nullptr}, + {X86_INS_VPMOVZXBW, nullptr}, + {X86_INS_VPMOVZXDQ, nullptr}, + {X86_INS_VPMOVZXWD, nullptr}, + {X86_INS_VPMOVZXWQ, nullptr}, + {X86_INS_VPMULDQ, nullptr}, + {X86_INS_VPMULHRSW, nullptr}, + {X86_INS_VPMULHUW, nullptr}, + {X86_INS_VPMULHW, nullptr}, + {X86_INS_VPMULLD, nullptr}, + {X86_INS_VPMULLQ, nullptr}, + {X86_INS_VPMULLW, nullptr}, + {X86_INS_VPMULUDQ, nullptr}, + {X86_INS_VPORD, nullptr}, + {X86_INS_VPORQ, nullptr}, + {X86_INS_VPOR, nullptr}, + {X86_INS_VPPERM, nullptr}, + {X86_INS_VPROTB, nullptr}, + {X86_INS_VPROTD, nullptr}, + {X86_INS_VPROTQ, nullptr}, + {X86_INS_VPROTW, nullptr}, + {X86_INS_VPSADBW, nullptr}, + {X86_INS_VPSCATTERDD, nullptr}, + {X86_INS_VPSCATTERDQ, nullptr}, + {X86_INS_VPSCATTERQD, nullptr}, + {X86_INS_VPSCATTERQQ, nullptr}, + {X86_INS_VPSHAB, nullptr}, + {X86_INS_VPSHAD, nullptr}, + {X86_INS_VPSHAQ, nullptr}, + {X86_INS_VPSHAW, nullptr}, + {X86_INS_VPSHLB, nullptr}, + {X86_INS_VPSHLD, nullptr}, + {X86_INS_VPSHLQ, nullptr}, + {X86_INS_VPSHLW, nullptr}, + {X86_INS_VPSHUFB, nullptr}, + {X86_INS_VPSHUFD, nullptr}, + {X86_INS_VPSHUFHW, nullptr}, + {X86_INS_VPSHUFLW, nullptr}, + {X86_INS_VPSIGNB, nullptr}, + {X86_INS_VPSIGND, nullptr}, + {X86_INS_VPSIGNW, nullptr}, + {X86_INS_VPSLLDQ, nullptr}, + {X86_INS_VPSLLD, nullptr}, + {X86_INS_VPSLLQ, nullptr}, + {X86_INS_VPSLLVD, nullptr}, + {X86_INS_VPSLLVQ, nullptr}, + {X86_INS_VPSLLW, nullptr}, + {X86_INS_VPSRAD, nullptr}, + {X86_INS_VPSRAQ, nullptr}, + {X86_INS_VPSRAVD, nullptr}, + {X86_INS_VPSRAVQ, nullptr}, + {X86_INS_VPSRAW, nullptr}, + {X86_INS_VPSRLDQ, nullptr}, + {X86_INS_VPSRLD, nullptr}, + {X86_INS_VPSRLQ, nullptr}, + {X86_INS_VPSRLVD, nullptr}, + {X86_INS_VPSRLVQ, nullptr}, + {X86_INS_VPSRLW, nullptr}, + {X86_INS_VPSUBB, nullptr}, + {X86_INS_VPSUBD, nullptr}, + {X86_INS_VPSUBQ, nullptr}, + {X86_INS_VPSUBSB, nullptr}, + {X86_INS_VPSUBSW, nullptr}, + {X86_INS_VPSUBUSB, nullptr}, + {X86_INS_VPSUBUSW, nullptr}, + {X86_INS_VPSUBW, nullptr}, + {X86_INS_VPTESTMD, nullptr}, + {X86_INS_VPTESTMQ, nullptr}, + {X86_INS_VPTESTNMD, nullptr}, + {X86_INS_VPTESTNMQ, nullptr}, + {X86_INS_VPTEST, nullptr}, + {X86_INS_VPUNPCKHBW, nullptr}, + {X86_INS_VPUNPCKHDQ, nullptr}, + {X86_INS_VPUNPCKHQDQ, nullptr}, + {X86_INS_VPUNPCKHWD, nullptr}, + {X86_INS_VPUNPCKLBW, nullptr}, + {X86_INS_VPUNPCKLDQ, nullptr}, + {X86_INS_VPUNPCKLQDQ, nullptr}, + {X86_INS_VPUNPCKLWD, nullptr}, + {X86_INS_VPXORD, nullptr}, + {X86_INS_VPXORQ, nullptr}, + {X86_INS_VPXOR, nullptr}, + {X86_INS_VRCP14PD, nullptr}, + {X86_INS_VRCP14PS, nullptr}, + {X86_INS_VRCP14SD, nullptr}, + {X86_INS_VRCP14SS, nullptr}, + {X86_INS_VRCP28PD, nullptr}, + {X86_INS_VRCP28PS, nullptr}, + {X86_INS_VRCP28SD, nullptr}, + {X86_INS_VRCP28SS, nullptr}, + {X86_INS_VRCPPS, nullptr}, + {X86_INS_VRCPSS, nullptr}, + {X86_INS_VRNDSCALEPD, nullptr}, + {X86_INS_VRNDSCALEPS, nullptr}, + {X86_INS_VRNDSCALESD, nullptr}, + {X86_INS_VRNDSCALESS, nullptr}, + {X86_INS_VROUNDPD, nullptr}, + {X86_INS_VROUNDPS, nullptr}, + {X86_INS_VROUNDSD, nullptr}, + {X86_INS_VROUNDSS, nullptr}, + {X86_INS_VRSQRT14PD, nullptr}, + {X86_INS_VRSQRT14PS, nullptr}, + {X86_INS_VRSQRT14SD, nullptr}, + {X86_INS_VRSQRT14SS, nullptr}, + {X86_INS_VRSQRT28PD, nullptr}, + {X86_INS_VRSQRT28PS, nullptr}, + {X86_INS_VRSQRT28SD, nullptr}, + {X86_INS_VRSQRT28SS, nullptr}, + {X86_INS_VRSQRTPS, nullptr}, + {X86_INS_VRSQRTSS, nullptr}, + {X86_INS_VSCATTERDPD, nullptr}, + {X86_INS_VSCATTERDPS, nullptr}, + {X86_INS_VSCATTERPF0DPD, nullptr}, + {X86_INS_VSCATTERPF0DPS, nullptr}, + {X86_INS_VSCATTERPF0QPD, nullptr}, + {X86_INS_VSCATTERPF0QPS, nullptr}, + {X86_INS_VSCATTERPF1DPD, nullptr}, + {X86_INS_VSCATTERPF1DPS, nullptr}, + {X86_INS_VSCATTERPF1QPD, nullptr}, + {X86_INS_VSCATTERPF1QPS, nullptr}, + {X86_INS_VSCATTERQPD, nullptr}, + {X86_INS_VSCATTERQPS, nullptr}, + {X86_INS_VSHUFPD, nullptr}, + {X86_INS_VSHUFPS, nullptr}, + {X86_INS_VSQRTPD, nullptr}, + {X86_INS_VSQRTPS, nullptr}, + {X86_INS_VSQRTSD, nullptr}, + {X86_INS_VSQRTSS, nullptr}, + {X86_INS_VSTMXCSR, nullptr}, + {X86_INS_VSUBPD, nullptr}, + {X86_INS_VSUBPS, nullptr}, + {X86_INS_VSUBSD, nullptr}, + {X86_INS_VSUBSS, nullptr}, + {X86_INS_VTESTPD, nullptr}, + {X86_INS_VTESTPS, nullptr}, + {X86_INS_VUNPCKHPD, nullptr}, + {X86_INS_VUNPCKHPS, nullptr}, + {X86_INS_VUNPCKLPD, nullptr}, + {X86_INS_VUNPCKLPS, nullptr}, + {X86_INS_VZEROALL, nullptr}, + {X86_INS_VZEROUPPER, nullptr}, + {X86_INS_WAIT, nullptr}, + {X86_INS_WBINVD, nullptr}, + {X86_INS_WRFSBASE, nullptr}, + {X86_INS_WRGSBASE, nullptr}, + {X86_INS_WRMSR, nullptr}, + {X86_INS_XABORT, nullptr}, + {X86_INS_XACQUIRE, nullptr}, + {X86_INS_XBEGIN, nullptr}, + {X86_INS_XCHG, &Capstone2LlvmIrTranslatorX86_impl::translateXchg}, + {X86_INS_XCRYPTCBC, nullptr}, + {X86_INS_XCRYPTCFB, nullptr}, + {X86_INS_XCRYPTCTR, nullptr}, + {X86_INS_XCRYPTECB, nullptr}, + {X86_INS_XCRYPTOFB, nullptr}, + {X86_INS_XEND, nullptr}, + {X86_INS_XGETBV, nullptr}, + {X86_INS_XLATB, &Capstone2LlvmIrTranslatorX86_impl::translateXlatb}, + {X86_INS_XRELEASE, nullptr}, + {X86_INS_XRSTOR, nullptr}, + {X86_INS_XRSTOR64, nullptr}, + {X86_INS_XRSTORS, nullptr}, + {X86_INS_XRSTORS64, nullptr}, + {X86_INS_XSAVE, nullptr}, + {X86_INS_XSAVE64, nullptr}, + {X86_INS_XSAVEC, nullptr}, + {X86_INS_XSAVEC64, nullptr}, + {X86_INS_XSAVEOPT, nullptr}, + {X86_INS_XSAVEOPT64, nullptr}, + {X86_INS_XSAVES, nullptr}, + {X86_INS_XSAVES64, nullptr}, + {X86_INS_XSETBV, nullptr}, + {X86_INS_XSHA1, nullptr}, + {X86_INS_XSHA256, nullptr}, + {X86_INS_XSTORE, nullptr}, + {X86_INS_XTEST, nullptr}, + {X86_INS_FDISI8087_NOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_FENI8087_NOP, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + + // pseudo instructions + {X86_INS_CMPSS, nullptr}, + {X86_INS_CMPSD, &Capstone2LlvmIrTranslatorX86_impl::translateCompareString}, + {X86_INS_CMPPS, nullptr}, + {X86_INS_CMPPD, nullptr}, + {X86_INS_VCMPSS, nullptr}, + {X86_INS_VCMPSD, nullptr}, + {X86_INS_VCMPPS, nullptr}, + {X86_INS_VCMPPD, nullptr}, + {X86_INS_ENDBR32, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + {X86_INS_ENDBR64, &Capstone2LlvmIrTranslatorX86_impl::translateNop}, + + {X86_INS_ENDING, nullptr}, // mark the end of the list of insn +}; + +} // namespace capstone2llvmir +} // namespace retdec