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
|
const std = @import("std");
const parser = @import("parser.zig");
const llvm = @import("llvm");
const target_m = llvm.target_machine;
const target = llvm.target;
const types = llvm.types;
const core = llvm.core;
pub const CodeGen = struct {
llvm_module: types.LLVMModuleRef,
pub fn init(arena: std.mem.Allocator) !*CodeGen {
// Initialize LLVM
_ = target.LLVMInitializeNativeTarget();
_ = target.LLVMInitializeNativeAsmPrinter();
_ = target.LLVMInitializeNativeAsmParser();
const module: types.LLVMModuleRef = core.LLVMModuleCreateWithName("module");
const self = try arena.create(CodeGen);
self.* = .{
.llvm_module = module,
};
return self;
}
pub fn deinit(self: *CodeGen) void {
// Generate code
const triple = target_m.LLVMGetDefaultTargetTriple();
var target_ref: types.LLVMTargetRef = undefined;
_ = target_m.LLVMGetTargetFromTriple(triple, &target_ref, null);
const target_machine = target_m.LLVMCreateTargetMachine(
target_ref,
triple,
"generic",
"",
types.LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault,
types.LLVMRelocMode.LLVMRelocDefault,
types.LLVMCodeModel.LLVMCodeModelDefault,
);
// Generate the object file
const filename = "output.o";
_ = target_m.LLVMTargetMachineEmitToFile(
target_machine,
self.llvm_module,
filename,
types.LLVMCodeGenFileType.LLVMObjectFile,
null,
);
std.debug.print("Object file generated: {s}\n", .{filename});
// Clean up LLVM resources
core.LLVMDisposeModule(self.llvm_module);
core.LLVMShutdown();
}
pub fn generate(self: *CodeGen) void {
const builder = core.LLVMCreateBuilder();
defer core.LLVMDisposeBuilder(builder);
const main_func_type = core.LLVMFunctionType(core.LLVMInt32Type(), null, 0, 0);
const main_func = core.LLVMAddFunction(self.llvm_module, "main", main_func_type);
const main_entry = core.LLVMAppendBasicBlock(main_func, "entrypoint");
core.LLVMPositionBuilderAtEnd(builder, main_entry);
var exit_func_params = [_]types.LLVMTypeRef{
core.LLVMInt32Type(),
};
const exit_func_type = core.LLVMFunctionType(core.LLVMInt32Type(), &exit_func_params, exit_func_params.len, 0);
const exit_func = core.LLVMAddFunction(self.llvm_module, "exit", exit_func_type);
var exit_func_args = [_]types.LLVMValueRef{
core.LLVMConstInt(core.LLVMInt32Type(), 7, 0),
};
const exit_func_ret = core.LLVMBuildCall2(builder, exit_func_type, exit_func, &exit_func_args, exit_func_args.len, "exit_call");
_ = core.LLVMBuildRet(builder, exit_func_ret);
}
};
|