Skip to content

Commit b5cf7d6

Browse files
committed
Adding support for MULX instruction.
1 parent 3fe61e8 commit b5cf7d6

File tree

3 files changed

+47
-3
lines changed

3 files changed

+47
-3
lines changed

src/capstone2llvmir/x86/x86.cpp

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
* @copyright (c) 2017 Avast Software, licensed under the MIT license
55
*/
66

7-
#include <iomanip>
8-
97
#include "capstone2llvmir/x86/x86_impl.h"
108

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

2619+
/**
2620+
* X86_INS_MULX
2621+
*/
2622+
void Capstone2LlvmIrTranslatorX86_impl::translateMulx(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb)
2623+
{
2624+
EXPECT_IS_TERNARY(i, xi, irb);
2625+
2626+
llvm::IntegerType* halfT = nullptr;
2627+
llvm::IntegerType* mulT = nullptr;
2628+
uint32_t otherOp = X86_REG_INVALID;
2629+
switch (xi->operands[0].size) {
2630+
case 4:
2631+
{
2632+
halfT = irb.getInt32Ty();
2633+
mulT = irb.getInt64Ty();
2634+
otherOp = X86_REG_EDX;
2635+
break;
2636+
}
2637+
case 8:
2638+
{
2639+
halfT = irb.getInt64Ty();
2640+
mulT = irb.getInt128Ty();
2641+
otherOp = X86_REG_RDX;
2642+
break;
2643+
}
2644+
default:
2645+
{
2646+
throw GenericError("Unhandled op size in translateMulx().");
2647+
}
2648+
}
2649+
op0 = loadOp(xi->operands[2], irb, halfT);
2650+
op1 = loadRegister(otherOp, irb, halfT);
2651+
2652+
op0 = irb.CreateZExt(op0, mulT);
2653+
op1 = irb.CreateZExt(op1, mulT);
2654+
2655+
auto* mul = irb.CreateMul(op0, op1);
2656+
auto* l = irb.CreateTrunc(mul, halfT);
2657+
auto* h = irb.CreateTrunc(irb.CreateLShr(mul, halfT->getBitWidth()), halfT);
2658+
2659+
// First operand is high destination register, second operand is low
2660+
storeRegister(xi->operands[1].reg, l, irb);
2661+
storeRegister(xi->operands[0].reg, h, irb);
2662+
}
2663+
26212664
/**
26222665
* X86_INS_NEG
26232666
*/

src/capstone2llvmir/x86/x86_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ class Capstone2LlvmIrTranslatorX86_impl :
318318
void translateMov(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
319319
void translateMoveString(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
320320
void translateMul(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
321+
void translateMulx(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
321322
void translateNeg(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
322323
void translateNop(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
323324
void translateNot(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);

src/capstone2llvmir/x86/x86_init.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,7 @@ Capstone2LlvmIrTranslatorX86_impl::_i2fm =
11061106
{X86_INS_MULPS, nullptr},
11071107
{X86_INS_MULSD, nullptr},
11081108
{X86_INS_MULSS, nullptr},
1109-
{X86_INS_MULX, nullptr},
1109+
{X86_INS_MULX, &Capstone2LlvmIrTranslatorX86_impl::translateMulx},
11101110
{X86_INS_FMUL, &Capstone2LlvmIrTranslatorX86_impl::translateFmul},
11111111
{X86_INS_FIMUL, &Capstone2LlvmIrTranslatorX86_impl::translateFmul},
11121112
{X86_INS_FMULP, &Capstone2LlvmIrTranslatorX86_impl::translateFmul},

0 commit comments

Comments
 (0)