26 : llvmContext(llvmContext), llvmIR(this->llvmContext) {
27 this->llvmModule = std::make_shared<llvm::Module>(
"tritonModule", this->llvmContext);
28 if (llvmModule ==
nullptr) {
39 std::sort(vars.begin(), vars.end());
42 std::vector<llvm::Type*> argsType;
43 argsType.resize(vars.size());
44 for (
triton::usize index = 0 ; index < vars.size() ; index++) {
45 switch (vars[index]->getBitvectorSize()) {
47 argsType[index] = llvm::Type::getInt8Ty(this->llvmContext);
50 argsType[index] = llvm::Type::getInt16Ty(this->llvmContext);
53 argsType[index] = llvm::Type::getInt32Ty(this->llvmContext);
56 argsType[index] = llvm::Type::getInt64Ty(this->llvmContext);
64 auto retSize = node->getBitvectorSize();
65 auto* retType = llvm::IntegerType::get(this->llvmContext, retSize);
66 auto* funcType = llvm::FunctionType::get(retType, argsType,
false );
67 auto* llvmFunc = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, fname, this->llvmModule.get());
70 llvm::Function::arg_iterator params = llvmFunc->arg_begin();
71 for (
const auto& node : vars) {
73 auto* param = params++;
74 param->setName(var->getName());
75 this->llvmVars[node] = param;
79 auto* llvmBasicBlock = llvm::BasicBlock::Create(this->llvmContext,
"entry", llvmFunc);
80 this->llvmIR.SetInsertPoint(llvmBasicBlock);
85 std::unordered_map<triton::ast::SharedAbstractNode, llvm::Value*> results;
88 this->createFunction(node, fname);
92 for (
const auto& node : nodes) {
93 if (node->getBitvectorSize()) {
94 results.insert(std::make_pair(node, this->do_convert(node, &results)));
99 this->llvmIR.CreateRet(results.at(node));
103 llvm::legacy::PassManager pm;
104 llvm::PassManagerBuilder pmb;
107 pmb.populateModulePassManager(pm);
108 pm.run(*this->llvmModule);
111 return this->llvmModule;
115 llvm::Value* TritonToLLVM::do_convert(
const triton::ast::SharedAbstractNode& node, std::unordered_map<triton::ast::SharedAbstractNode, llvm::Value*>* results) {
120 std::vector<llvm::Value*> children;
121 for (
auto&& n : node->getChildren()) {
123 if (n->getBitvectorSize() == 0) {
124 children.emplace_back(
nullptr);
127 children.emplace_back(results->at(n));
131 switch (node->getType()) {
134 llvm::Function* bswap =
nullptr;
135 switch (node->getBitvectorSize()) {
136 case triton::bitsize::byte: bswap = llvm::Intrinsic::getDeclaration(this->llvmModule.get(), llvm::Intrinsic::bswap, llvm::Type::getInt8Ty(this->llvmContext));
break;
137 case triton::bitsize::word: bswap = llvm::Intrinsic::getDeclaration(this->llvmModule.get(), llvm::Intrinsic::bswap, llvm::Type::getInt16Ty(this->llvmContext));
break;
138 case triton::bitsize::dword: bswap = llvm::Intrinsic::getDeclaration(this->llvmModule.get(), llvm::Intrinsic::bswap, llvm::Type::getInt32Ty(this->llvmContext));
break;
139 case triton::bitsize::qword: bswap = llvm::Intrinsic::getDeclaration(this->llvmModule.get(), llvm::Intrinsic::bswap, llvm::Type::getInt64Ty(this->llvmContext));
break;
143 return this->llvmIR.CreateCall(bswap, children[0]);
147 return this->llvmIR.CreateAdd(children[0], children[1]);
150 return this->llvmIR.CreateAnd(children[0], children[1]);
153 return this->llvmIR.CreateAShr(children[0], children[1]);
156 return this->llvmIR.CreateLShr(children[0], children[1]);
159 return this->llvmIR.CreateMul(children[0], children[1]);
162 return this->llvmIR.CreateNot(this->llvmIR.CreateAnd(children[0], children[1]));
165 return this->llvmIR.CreateNeg(children[0]);
168 return this->llvmIR.CreateNot(this->llvmIR.CreateOr(children[0], children[1]));
171 return this->llvmIR.CreateNot(children[0]);
174 return this->llvmIR.CreateOr(children[0], children[1]);
178 auto rot = triton::ast::getInteger<triton::uint64>(node->getChildren()[1]);
179 auto size = node->getBitvectorSize();
180 return this->llvmIR.CreateOr(this->llvmIR.CreateShl(children[0], rot % size), this->llvmIR.CreateLShr(children[0], (size - (rot % size))));
185 auto rot = triton::ast::getInteger<triton::uint64>(node->getChildren()[1]);
186 auto size = node->getBitvectorSize();
187 return this->llvmIR.CreateOr(this->llvmIR.CreateLShr(children[0], rot % size), this->llvmIR.CreateShl(children[0], (size - (rot % size))));
191 return this->llvmIR.CreateSDiv(children[0], children[1]);
194 return this->llvmIR.CreateICmpSGE(children[0], children[1]);
197 return this->llvmIR.CreateICmpSGT(children[0], children[1]);
200 return this->llvmIR.CreateShl(children[0], children[1]);
203 return this->llvmIR.CreateICmpSLE(children[0], children[1]);
206 return this->llvmIR.CreateICmpSLT(children[0], children[1]);
209 auto* LHS = children[0];
210 auto* RHS = children[1];
211 return this->llvmIR.CreateSRem(this->llvmIR.CreateAdd(this->llvmIR.CreateSRem(LHS, RHS), RHS), RHS);
215 return this->llvmIR.CreateSRem(children[0], children[1]);
218 return this->llvmIR.CreateSub(children[0], children[1]);
221 return this->llvmIR.CreateUDiv(children[0], children[1]);
224 return this->llvmIR.CreateICmpUGE(children[0], children[1]);
227 return this->llvmIR.CreateICmpUGT(children[0], children[1]);
230 return this->llvmIR.CreateICmpULE(children[0], children[1]);
233 return this->llvmIR.CreateICmpULT(children[0], children[1]);
236 return this->llvmIR.CreateURem(children[0], children[1]);
239 return this->llvmIR.CreateNot(this->llvmIR.CreateXor(children[0], children[1]));
242 return this->llvmIR.CreateXor(children[0], children[1]);
245 return llvm::ConstantInt::get(this->llvmContext, llvm::APInt(node->getBitvectorSize(),
static_cast<uint64_t
>(node->evaluate()),
false));
248 auto dstSize = node->getBitvectorSize();
249 auto finalNode = this->llvmIR.CreateZExt(children[0], llvm::IntegerType::get(this->llvmContext, dstSize));
251 for (
triton::usize index = 1; index < children.size(); index++) {
252 finalNode = this->llvmIR.CreateShl(finalNode, node->getChildren()[index]->getBitvectorSize());
253 auto* n = this->llvmIR.CreateZExt(children[index], llvm::IntegerType::get(this->llvmContext, dstSize));
254 finalNode = this->llvmIR.CreateOr(finalNode, n);
261 return this->llvmIR.CreateICmpNE(children[0], children[1]);
264 return this->llvmIR.CreateICmpEQ(children[0], children[1]);
267 auto low = triton::ast::getInteger<triton::uint64>(node->getChildren()[1]);
268 auto dstSize = node->getChildren()[2]->getBitvectorSize();
269 auto* value = children[2];
272 return this->llvmIR.CreateTrunc(value, llvm::IntegerType::get(this->llvmContext, node->getBitvectorSize()));
275 return this->llvmIR.CreateTrunc(this->llvmIR.CreateLShr(value, low), llvm::IntegerType::get(this->llvmContext, node->getBitvectorSize()));
279 return this->llvmIR.CreateSelect(children[0], children[1], children[2]);
282 auto* truenode = llvm::ConstantInt::get(this->llvmContext, llvm::APInt(1, 1));
283 return this->llvmIR.CreateICmpEQ(this->llvmIR.CreateAnd(children), truenode);
287 auto* truenode = llvm::ConstantInt::get(this->llvmContext, llvm::APInt(1, 1));
288 return this->llvmIR.CreateICmpEQ(this->llvmIR.CreateNot(children[0]), truenode);
292 auto* truenode = llvm::ConstantInt::get(this->llvmContext, llvm::APInt(1, 1));
293 return this->llvmIR.CreateICmpEQ(this->llvmIR.CreateOr(children), truenode);
297 auto* child0 = children[0];
298 auto* child1 = children[1];
299 auto* current = this->llvmIR.CreateXor(child0, child1);
301 for (
triton::usize index = 2; index < children.size(); index++) {
302 current = this->llvmIR.CreateXor(current, children[index]);
305 auto* truenode = llvm::ConstantInt::get(this->llvmContext, llvm::APInt(1, 1));
306 return this->llvmIR.CreateICmpEQ(current, truenode);
313 auto* ptr = this->llvmIR.CreateIntToPtr(children[1], llvm::Type::getInt8PtrTy(this->llvmContext));
314 return this->llvmIR.CreateLoad(llvm::Type::getInt8Ty(this->llvmContext), ptr);
318 auto* ptr = this->llvmIR.CreateIntToPtr(children[1], llvm::Type::getInt8PtrTy(this->llvmContext));
319 return this->llvmIR.CreateStore(children[2], ptr);
323 return this->llvmIR.CreateSExt(children[1], llvm::IntegerType::get(this->llvmContext, node->getBitvectorSize()));
326 return this->llvmVars.at(node);
329 return this->llvmIR.CreateZExt(children[1], llvm::IntegerType::get(this->llvmContext, node->getBitvectorSize()));
TRITON_EXPORT std::shared_ptr< llvm::Module > convert(const triton::ast::SharedAbstractNode &node, const char *fname="__triton", bool optimize=false)
Lifts a symbolic expression and all its references to LLVM format. fname represents the name of the L...
TRITON_EXPORT TritonToLLVM(llvm::LLVMContext &llvmContext)
Constructor.
The exception class used by all AST lifting (e.g z3 <-> triton).
The exception class used by the lifting engine.
std::vector< SharedAbstractNode > childrenExtraction(const SharedAbstractNode &node, bool unroll, bool revert)
Returns node and all its children of an AST sorted topologically. If unroll is true,...
std::shared_ptr< triton::ast::AbstractNode > SharedAbstractNode
Shared Abstract Node.
std::deque< SharedAbstractNode > search(const SharedAbstractNode &node, triton::ast::ast_e match)
Returns a deque of collected matched nodes via a depth-first pre order traversal.
constexpr triton::uint32 byte
byte size in bit
constexpr triton::uint32 dword
dword size in bit
constexpr triton::uint32 qword
qword size in bit
constexpr triton::uint32 word
word size in bit
std::size_t usize
unsigned MAX_INT 32 or 64 bits according to the CPU.