Skip to content

Commit

Permalink
Adding support for MULX instruction.
Browse files Browse the repository at this point in the history
  • Loading branch information
lvella committed Apr 19, 2024
1 parent 3fe61e8 commit b5cf7d6
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 deletions.
47 changes: 45 additions & 2 deletions src/capstone2llvmir/x86/x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
* @copyright (c) 2017 Avast Software, licensed under the MIT license
*/

#include <iomanip>

#include "capstone2llvmir/x86/x86_impl.h"

namespace retdec {
Expand Down Expand Up @@ -2618,6 +2616,51 @@ void Capstone2LlvmIrTranslatorX86_impl::translateMul(cs_insn* i, cs_x86* xi, llv
storeRegister(X86_REG_CF, f, irb);
}

/**
* X86_INS_MULX
*/
void Capstone2LlvmIrTranslatorX86_impl::translateMulx(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb)
{
EXPECT_IS_TERNARY(i, xi, irb);

llvm::IntegerType* halfT = nullptr;
llvm::IntegerType* mulT = nullptr;
uint32_t otherOp = X86_REG_INVALID;
switch (xi->operands[0].size) {
case 4:
{
halfT = irb.getInt32Ty();
mulT = irb.getInt64Ty();
otherOp = X86_REG_EDX;
break;
}
case 8:
{
halfT = irb.getInt64Ty();
mulT = irb.getInt128Ty();
otherOp = X86_REG_RDX;
break;
}
default:
{
throw GenericError("Unhandled op size in translateMulx().");
}
}
op0 = loadOp(xi->operands[2], irb, halfT);
op1 = loadRegister(otherOp, irb, halfT);

op0 = irb.CreateZExt(op0, mulT);
op1 = irb.CreateZExt(op1, mulT);

auto* mul = irb.CreateMul(op0, op1);
auto* l = irb.CreateTrunc(mul, halfT);
auto* h = irb.CreateTrunc(irb.CreateLShr(mul, halfT->getBitWidth()), halfT);

// First operand is high destination register, second operand is low
storeRegister(xi->operands[1].reg, l, irb);
storeRegister(xi->operands[0].reg, h, irb);
}

/**
* X86_INS_NEG
*/
Expand Down
1 change: 1 addition & 0 deletions src/capstone2llvmir/x86/x86_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ class Capstone2LlvmIrTranslatorX86_impl :
void translateMov(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
void translateMoveString(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
void translateMul(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
void translateMulx(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
void translateNeg(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
void translateNop(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
void translateNot(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
Expand Down
2 changes: 1 addition & 1 deletion src/capstone2llvmir/x86/x86_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1106,7 +1106,7 @@ Capstone2LlvmIrTranslatorX86_impl::_i2fm =
{X86_INS_MULPS, nullptr},
{X86_INS_MULSD, nullptr},
{X86_INS_MULSS, nullptr},
{X86_INS_MULX, nullptr},
{X86_INS_MULX, &Capstone2LlvmIrTranslatorX86_impl::translateMulx},
{X86_INS_FMUL, &Capstone2LlvmIrTranslatorX86_impl::translateFmul},
{X86_INS_FIMUL, &Capstone2LlvmIrTranslatorX86_impl::translateFmul},
{X86_INS_FMULP, &Capstone2LlvmIrTranslatorX86_impl::translateFmul},
Expand Down

0 comments on commit b5cf7d6

Please sign in to comment.