diff --git a/src/codegen.zig b/src/codegen.zig index 37e39ac..b0d652a 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -2,6 +2,11 @@ const std = @import("std"); const ast = @import("ast.zig"); const llvm = @import("llvm.zig"); +fn sliceify(non_slice: ?[*]const u8) []const u8 { + if (non_slice == null) return ""; + return non_slice.?[0..std.mem.len(u8, non_slice.?)]; +} + pub const Codegen = struct { allocator: *std.mem.Allocator, @@ -62,9 +67,8 @@ pub const Codegen = struct { } pub fn gen(self: *Codegen, root: *ast.Node) !void { - //std.debug.warn("cgen: init native target\n"); - //_ = llvm.LLVMInitializeNativeTarget(); std.debug.warn("cgen: start gen\n"); + _ = llvm.LLVMInitializeNativeTarget(); var mod = llvm.LLVMModuleCreateWithName(c"awoo").?; defer llvm.LLVMDisposeModule(mod); @@ -75,15 +79,65 @@ pub const Codegen = struct { } var err: ?[*]u8 = null; + defer llvm.LLVMDisposeMessage(err); + _ = llvm.LLVMVerifyModule( mod, llvm.LLVMVerifierFailureAction.LLVMAbortProcessAction, &err, ); - llvm.LLVMDisposeMessage(err); if (llvm.LLVMWriteBitcodeToFile(mod, c"awoo.bc") != 0) { - std.debug.warn("error writing bitcode to file\n"); + std.debug.warn("error writing bitcode to file: {}\n", sliceify(err)); + + // TODO return error value + @panic("compile error"); + } + + //llvm.InitializeAllTargetInfos(); + //llvm.InitializeAllTargets(); + //llvm.InitializeAllTargetMCs(); + //llvm.InitializeAllAsmParsers(); + //llvm.InitializeAllAsmPrinters(); + + var engine: llvm.LLVMExecutionEngineRef = undefined; + if (llvm.LLVMCreateExecutionEngineForModule(&engine, mod, &err) != 0) { + std.debug.warn("failed to create execution engine: {}\n", sliceify(err)); + + // TODO return error value + @panic("compile error"); + } + + var machine = llvm.LLVMGetExecutionEngineTargetMachine(engine); + defer llvm.LLVMDisposeTargetMachine(machine); + + var target = llvm.LLVMGetTargetMachineTarget(machine); + var target_data = llvm.LLVMCreateTargetDataLayout(machine); + var data_layout = llvm.LLVMCopyStringRepOfTargetData(target_data); + llvm.LLVMSetDataLayout(mod, data_layout); + + var outpath = try std.mem.dupe(self.allocator, u8, "output.o"); + var outpath_cstr = try std.cstr.addNullByte(self.allocator, outpath); + + var desc = llvm.LLVMGetTargetDescription(target); + var features = llvm.LLVMGetTargetMachineFeatureString(machine); + var triple = llvm.LLVMGetTargetMachineTriple(machine); + + std.debug.warn("target: {}\n", sliceify(desc)); + std.debug.warn("triple: {}\n", sliceify(triple)); + std.debug.warn("features: {}\n", sliceify(features)); + + if (llvm.LLVMTargetMachineEmitToFile( + machine, + mod, + outpath_cstr.ptr, + llvm.LLVMCodeGenFileType.LLVMObjectFile, + &err, + ) != 0) { + std.debug.warn("failed to emit to file: {}\n", sliceify(err)); + + // TODO return error value + @panic("compile error"); } } }; diff --git a/src/llvm.zig b/src/llvm.zig index f849857..b8427ae 100644 --- a/src/llvm.zig +++ b/src/llvm.zig @@ -4,6 +4,7 @@ pub const llvm = @cImport({ @cInclude("llvm-c/Core.h"); @cInclude("llvm-c/ExecutionEngine.h"); @cInclude("llvm-c/Target.h"); + @cInclude("llvm-c/TargetMachine.h"); @cInclude("llvm-c/Analysis.h"); @cInclude("llvm-c/BitWriter.h"); @@ -15,17 +16,4 @@ pub const llvm = @cImport({ usingnamespace llvm; -//pub const LLVMModuleRef = llvm.LLVMModuleRef; -//pub const LLVMInt32Type = llvm.LLVMInt32Type; -//pub const LLVMModuleCreateWithName = llvm.LLVMModuleCreateWithName; -//pub const LLVMFunctionType = llvm.LLVMFunctionType; -//pub const LLVMAddFunction = llvm.LLVMAddFunction; -// -//pub const LLVMBasicBlockRef = llvm.LLVMBasicBlockRef; -//pub const LLVMAppendBasicBlock = llvm.LLVMAppendBasicBlock; -// -//pub const LLVMBuilderRef = llvm.LLVMBuilderRef; -//pub const LLVMCreateBuilder = llvm.LLVMCreateBuilder; -//pub const LLVMPositionBuilderAtEnd = llvm.LLVMPositionBuilderAtEnd; - pub const LLVMTypeList = std.ArrayList(llvm.LLVMTypeRef);