Skip to content

Commit

Permalink
Add support for Tzcnt and Lzcnt
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralender committed Apr 29, 2024
1 parent 58b041e commit fd1b568
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 2 deletions.
24 changes: 24 additions & 0 deletions src/capstone2llvmir/x86/x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3364,6 +3364,7 @@ void Capstone2LlvmIrTranslatorX86_impl::translateShiftX(cs_insn* i, cs_x86* xi,
case X86_INS_SHR: return llvm::Instruction::BinaryOps::LShr;
case X86_INS_SAR: return llvm::Instruction::BinaryOps::AShr;
case X86_INS_SHL: return llvm::Instruction::BinaryOps::Shl;
default: assert(false);
}
}();

Expand Down Expand Up @@ -5444,5 +5445,28 @@ void Capstone2LlvmIrTranslatorX86_impl::translateRdtscp(cs_insn* i, cs_x86* xi,
storeRegister(X86_REG_ECX, irb.CreateExtractValue(c, {2}), irb);
}

void Capstone2LlvmIrTranslatorX86_impl::translateTzcntOrLzcnt(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb)
{
EXPECT_IS_BINARY(i, xi, irb);

std::tie(op0, op1) = loadOpBinary(xi, irb);

storeRegister(X86_REG_CF, generateZeroFlag(op1, irb), irb);

op0 = irb.CreateIntrinsic(
i->id == X86_INS_LZCNT ? llvm::Intrinsic::ctlz : llvm::Intrinsic::cttz,
{op1->getType()},
{op1, irb.getFalse()});

storeRegister(X86_REG_OF, irb.getFalse(), irb); // undef
storeRegister(X86_REG_SF, irb.getFalse(), irb); // undef
storeRegister(X86_REG_PF, irb.getFalse(), irb); // undef
storeRegister(X86_REG_AF, irb.getFalse(), irb); // undef

storeRegister(X86_REG_ZF, generateZeroFlag(op0, irb), irb);

storeOp(xi->operands[0], op0, irb);
}

} // namespace capstone2llvmir
} // namespace retdec
1 change: 1 addition & 0 deletions src/capstone2llvmir/x86/x86_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ class Capstone2LlvmIrTranslatorX86_impl :
void translateXchg(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
void translateXlatb(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
void translateXor(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
void translateTzcntOrLzcnt(cs_insn* i, cs_x86* xi, llvm::IRBuilder<>& irb);
};

} // namespace capstone2llvmir
Expand Down
4 changes: 2 additions & 2 deletions src/capstone2llvmir/x86/x86_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,7 @@ Capstone2LlvmIrTranslatorX86_impl::_i2fm =
{X86_INS_LSS, &Capstone2LlvmIrTranslatorX86_impl::translateLoadFarPtr},
{X86_INS_LTR, nullptr},
{X86_INS_XADD, &Capstone2LlvmIrTranslatorX86_impl::translateAdd},
{X86_INS_LZCNT, nullptr},
{X86_INS_LZCNT, &Capstone2LlvmIrTranslatorX86_impl::translateTzcntOrLzcnt},
{X86_INS_MASKMOVDQU, nullptr},
{X86_INS_MAXPD, nullptr},
{X86_INS_MAXPS, nullptr},
Expand Down Expand Up @@ -1320,7 +1320,7 @@ Capstone2LlvmIrTranslatorX86_impl::_i2fm =
{X86_INS_TEST, &Capstone2LlvmIrTranslatorX86_impl::translateAnd},
{X86_INS_UD2, &Capstone2LlvmIrTranslatorX86_impl::translateNop},
{X86_INS_FTST, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop},
{X86_INS_TZCNT, nullptr},
{X86_INS_TZCNT, &Capstone2LlvmIrTranslatorX86_impl::translateTzcntOrLzcnt},
{X86_INS_TZMSK, nullptr},
{X86_INS_FUCOMPI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop},
{X86_INS_FUCOMI, &Capstone2LlvmIrTranslatorX86_impl::translateFucomPop},
Expand Down

0 comments on commit fd1b568

Please sign in to comment.