#include "llvm/IR/Function.h" #include "llvm/PassManager.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/IR/IRBuilder.h" #include "llvm/Support/raw_ostream.h" #include "llvm/IR/LLVMContext.h" #include "llvm/ExecutionEngine/JIT.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/Support/TargetSelect.h" #include "llvm/CodeGen/MachineCodeInfo.h" #include "llvm/IR/Module.h" #include #include using namespace llvm; Module* makeLLVMModule(); void printHexData(void * data, uint32_t address, int len); int main(int argc, char**argv) { std::string errorDescription; Module* Mod = makeLLVMModule(); // Mod->setTargetTriple("arm-Unknown"); verifyModule(*Mod, PrintMessageAction); PassManager PM; PM.add(createPrintModulePass(&outs())); PM.run(*Mod); InitializeAllTargets(); InitializeAllTargetMCs(); ExecutionEngine* engine = EngineBuilder(Mod) .setEngineKind(EngineKind::JIT) .setUseMCJIT(true) .setErrorStr(&errorDescription) .setMArch("arm") // .setMCPU("arm966") .create(); MachineCodeInfo codeInfo; if (!engine) { std::cout << "Error creating Execution Engine: " << errorDescription << std::endl; exit(1); } Function* gcd = Mod->getFunction("gcd"); engine->runJITOnFunction(gcd, &codeInfo); std::cout << "Code at 0x" << std::hex << reinterpret_cast(codeInfo.address()) << " size " << std::dec << codeInfo.size() << std::endl; printHexData(codeInfo.address(), 0, codeInfo.size()); delete Mod; return 0; } Module* makeLLVMModule() { Module* mod = new Module("tut2", getGlobalContext()); Constant* c = mod->getOrInsertFunction("gcd", (Type *) Type::getInt32Ty(getGlobalContext()), Type::getInt32Ty(getGlobalContext()), Type::getInt32Ty(getGlobalContext()), NULL); Function* gcd = cast(c); Function::arg_iterator args = gcd->arg_begin(); Value* x = args++; x->setName("x"); Value* y = args++; y->setName("y"); BasicBlock* entry = BasicBlock::Create(getGlobalContext(), "entry", gcd); BasicBlock* ret = BasicBlock::Create(getGlobalContext(), "return", gcd); BasicBlock* cond_false = BasicBlock::Create(getGlobalContext(), "cond_false", gcd); BasicBlock* cond_true = BasicBlock::Create(getGlobalContext(), "cond_true", gcd); BasicBlock* cond_false_2 = BasicBlock::Create(getGlobalContext(), "cond_false", gcd); IRBuilder<> builder(entry); Value* xEqualsY = builder.CreateICmpEQ(x, y, "tmp"); builder.CreateCondBr(xEqualsY, ret, cond_false); builder.SetInsertPoint(ret); builder.CreateRet(x); builder.SetInsertPoint(cond_false); Value* xLessThanY = builder.CreateICmpULT(x, y, "tmp"); builder.CreateCondBr(xLessThanY, cond_true, cond_false_2); builder.SetInsertPoint(cond_true); Value* yMinusX = builder.CreateSub(y, x, "tmp"); Value* recur_1 = builder.CreateCall2(gcd, x, yMinusX, "tmp"); builder.CreateRet(recur_1); builder.SetInsertPoint(cond_false_2); Value* xMinusY = builder.CreateSub(x, y, "tmp"); Value* recur_2 = builder.CreateCall2(gcd, xMinusY, y, "tmp"); builder.CreateRet(recur_2); return mod; } void printHexData(void * data, uint32_t address, int len) { int pos = 0; while (pos < len) { std::cout << std::setfill('0') << std::setw(16) << std::hex << ((address + pos) & 0xFFFFFFFF) << " "; for (int i = 0; i < 8 && pos < len; pos++, i++) std::cout << std::setfill('0') << std::setw(2) << std::hex << (static_cast(static_cast(data)[pos]) & 0xFF) << " "; std::cout << " "; for (int i = 0; i < 8 && pos < len; pos++, i++) std::cout << std::setfill('0') << std::setw(2) << std::hex << (static_cast(static_cast(data)[pos]) & 0xFF) << " "; std::cout << std::endl; } }