Created
December 6, 2011 14:15
-
-
Save snaka/1438344 to your computer and use it in GitHub Desktop.
"Hello world" する LLVM assembly code を生成する C++ コード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <llvm/LLVMContext.h> | |
#include <llvm/Module.h> | |
#include <llvm/BasicBlock.h> | |
#include <llvm/CallingConv.h> | |
#include <llvm/Constants.h> | |
#include <llvm/Function.h> | |
#include <llvm/GlobalVariable.h> | |
#include <llvm/Instructions.h> | |
#include <llvm/PassManager.h> | |
#include <llvm/Analysis/Verifier.h> | |
#include <llvm/Assembly/PrintModulePass.h> | |
#include <llvm/Support/raw_ostream.h> | |
using namespace llvm; | |
Function* func_main; | |
/* | |
以下のCソースコードと等価な LLVM モジュールを生成します。 | |
int puts(const char*); | |
int main(int argc, char** argv) { | |
puts("Hello world"); | |
return 0; | |
} | |
*/ | |
Module* makeLLVMModule() { | |
// モジュール生成 | |
Module * mod = new Module("Hello world module", getGlobalContext()); | |
// | |
// 関数の宣言 | |
// | |
// main関数の宣言 | |
std::vector<const Type*> mainFuncTyArgs; | |
FunctionType* mainFuncTy = FunctionType::get( | |
/* 戻り値の型 */ IntegerType::get(mod->getContext(), 32), | |
/* 関数の引数 */ mainFuncTyArgs, | |
/* 可変引数か? */ false | |
); | |
func_main = Function::Create( | |
/* 関数の型 */ mainFuncTy, | |
/* Likage */ GlobalValue::ExternalLinkage, | |
/* 関数名 */ "main", mod | |
); | |
func_main->setCallingConv(CallingConv::C); | |
// C標準ライブラリputs関数のプロトタイプ宣言 | |
std::vector<const Type*> printfFuncTyArgs; | |
printfFuncTyArgs.push_back(PointerType::get(IntegerType::get(mod->getContext(), 8), 0)); | |
FunctionType* printfFuncTy = FunctionType::get( | |
/* 戻り値の型 */ IntegerType::get(mod->getContext(), 32), | |
/* 関数の引数 */ printfFuncTyArgs, | |
/* 可変引数か? */ false | |
); | |
Function* func_printf = Function::Create( | |
/* 関数の型 */ printfFuncTy, | |
/* Linkage */ GlobalValue::ExternalLinkage, | |
/* 関数名 */ "puts", mod | |
); | |
func_printf->setCallingConv(CallingConv::C); | |
// グローバル変数(定数)の宣言 | |
ArrayType* arrayTy = ArrayType::get(IntegerType::get(mod->getContext(), 8), 18); | |
GlobalVariable* gvar = new GlobalVariable( | |
/* モジュール */ *mod, | |
/* 型 */ arrayTy, | |
/* 定数? */ true, | |
/* Linkage */ GlobalValue::PrivateLinkage, | |
/* 初期化子 */ 0, // 初期化子あり | |
/* 名前 */ ".str" | |
); | |
// グローバル変数(定数)の初期化 | |
Constant* const_hello = ConstantArray::get(mod->getContext(), "Hello llvm world.", true); | |
ConstantInt* const_zero = ConstantInt::get(mod->getContext(), APInt(32, StringRef("0"), 10)); | |
std::vector<Constant*> constants; | |
constants.push_back(const_zero); | |
constants.push_back(const_zero); | |
Constant* const_ptr = ConstantExpr::getGetElementPtr(gvar, &constants[0], constants.size()); | |
gvar->setInitializer(const_hello); | |
// main 関数の定義 | |
{ | |
BasicBlock* main_block = BasicBlock::Create(mod->getContext(), "entry", func_main, 0); | |
// puts("Hello llvm world."); | |
CallInst* call_printf = CallInst::Create(func_printf, const_ptr, "", main_block); | |
call_printf->setCallingConv(CallingConv::C); | |
// return 0 | |
ReturnInst::Create(mod->getContext(), const_zero, main_block); | |
} | |
// 生成したモジュールを返す | |
return mod; | |
} | |
int main(int argc, char** argv) { | |
// モジュールを作成 | |
Module* mod = makeLLVMModule(); | |
verifyModule(*mod, PrintMessageAction); | |
// モジュールのLLVMアセンブリコードを標準出力に出力 | |
PassManager pm; | |
pm.add(createPrintModulePass(&outs())); | |
pm.run(*mod); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment