-
Notifications
You must be signed in to change notification settings - Fork 16
/
main.c
97 lines (73 loc) · 3.26 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <llvm-c/Core.h>
#include <llvm-c/BitWriter.h>
int main(int argc, char *argv[]) {
LLVMContextRef context = LLVMGetGlobalContext();
LLVMModuleRef module = LLVMModuleCreateWithNameInContext("meu_modulo.bc", context);
LLVMBuilderRef builder = LLVMCreateBuilderInContext(context);
// criação da função para adicionar ao módulo.
LLVMTypeRef addParams[] = {LLVMInt64Type(), LLVMInt64Type()};
LLVMTypeRef addFuncType = LLVMFunctionType(LLVMInt64Type(), addParams, 2, 0);
LLVMValueRef soma = LLVMAddFunction(module, "soma", addFuncType);
// criação de um bloco básico para adicionar o código principal da função "soma"
LLVMBasicBlockRef entryFnSoma = LLVMAppendBasicBlock(soma, "entry");
// Declara o bloco de saída.
LLVMBasicBlockRef exitFnSoma = LLVMAppendBasicBlock(soma, "exit");
LLVMPositionBuilderAtEnd(builder, entryFnSoma);
// LLVMValueRef LLVMGetParam(LLVMValueRef Fn, unsigned Index);
LLVMValueRef tmp =
LLVMBuildAdd(builder, LLVMGetParam(soma, 0), LLVMGetParam(soma, 1), "tmp");
// Cria um salto para o bloco de saída.
LLVMBuildBr(builder, exitFnSoma);
// Adiciona o bloco de saída.
LLVMPositionBuilderAtEnd(builder, exitFnSoma);
// LLVMValueRef tmp1 = LLVMBuildLoad(builder, tmp, "ret");
LLVMBuildRet(builder, tmp);
// Cria um valor zero para colocar no retorno para o main.
LLVMValueRef Zero64 = LLVMConstInt(LLVMInt64Type(), 0, false);
// Declara o tipo do retorno da função main.
LLVMTypeRef mainFnReturnType = LLVMInt64TypeInContext(context);
// Cria a função main.
LLVMValueRef mainFn = LLVMAddFunction(module, "main", LLVMFunctionType(mainFnReturnType, NULL, 0, 0));
// Declara o bloco de entrada.
LLVMBasicBlockRef entryBlock = LLVMAppendBasicBlockInContext(context, mainFn, "entry");
// Declara o bloco de saída.
LLVMBasicBlockRef exitBasicBlock = LLVMAppendBasicBlock(mainFn, "exit");
// Adiciona o bloco de entrada.
LLVMPositionBuilderAtEnd(builder, entryBlock);
// Cria o valor de retorno e inicializa com zero.
LLVMValueRef returnVal = LLVMBuildAlloca(builder, LLVMInt64Type(), "retorno");
LLVMBuildStore(builder, Zero64, returnVal);
// Declara as variáveis a,b e c.
LLVMValueRef a = LLVMBuildAlloca(builder, LLVMInt64Type(), "a");
LLVMValueRef b = LLVMBuildAlloca(builder, LLVMInt64Type(), "b");
// Inicializa as variáveis.
LLVMBuildStore(builder, LLVMConstInt(LLVMInt64Type(), 1, false), a);
LLVMBuildStore(builder, LLVMConstInt(LLVMInt64Type(), 2, false), b);
LLVMValueRef args[2] = {
LLVMBuildLoad(builder, a, ""),
LLVMBuildLoad(builder, b, "")
};
LLVMValueRef res = LLVMBuildCall(
builder,
soma,
args,
2,
"res"
);
LLVMBuildStore(builder, res, returnVal);
// Cria um salto para o bloco de saída.
LLVMBuildBr(builder, exitBasicBlock);
// Adiciona o bloco de saída.
LLVMPositionBuilderAtEnd(builder, exitBasicBlock);
// Cria o return.
LLVMBuildRet(builder, LLVMBuildLoad(builder, returnVal, ""));
// Imprime o código do módulo.
LLVMDumpModule(module);
// Escreve para um arquivo no formato bitcode.
if (LLVMWriteBitcodeToFile(module, "meu_modulo.bc") != 0) {
fprintf(stderr, "error writing bitcode to file, skipping\n");
}
}