| author | |
| committer | |
| log | 071417161d5d7ab91c32073693590ef161017dbe |
| tree | 891bfd9fecd90b9b341d95dfb78399788f62c3ed |
| parent | 4a0d64300bd9ab1a8c35c634856396e3413200f1 |
6 files changed, 813 insertions(+), 129 deletions(-)
CMakeLists.txt+1-1| ... | ... | @@ -527,7 +527,6 @@ set(ZIG_STAGE2_SOURCES |
| 527 | 527 | "${CMAKE_SOURCE_DIR}/src/codegen/aarch64.zig" |
| 528 | 528 | "${CMAKE_SOURCE_DIR}/src/codegen/arm.zig" |
| 529 | 529 | "${CMAKE_SOURCE_DIR}/src/codegen/c.zig" |
| 530 | "${CMAKE_SOURCE_DIR}/src/codegen/llvm.zig" | |
| 531 | 530 | "${CMAKE_SOURCE_DIR}/src/codegen/riscv64.zig" |
| 532 | 531 | "${CMAKE_SOURCE_DIR}/src/codegen/spu-mk2.zig" |
| 533 | 532 | "${CMAKE_SOURCE_DIR}/src/codegen/wasm.zig" |
| ... | ... | @@ -549,6 +548,7 @@ set(ZIG_STAGE2_SOURCES |
| 549 | 548 | "${CMAKE_SOURCE_DIR}/src/link/cbe.h" |
| 550 | 549 | "${CMAKE_SOURCE_DIR}/src/link/msdos-stub.bin" |
| 551 | 550 | "${CMAKE_SOURCE_DIR}/src/liveness.zig" |
| 551 | "${CMAKE_SOURCE_DIR}/src/llvm_backend.zig" | |
| 552 | 552 | "${CMAKE_SOURCE_DIR}/src/llvm_bindings.zig" |
| 553 | 553 | "${CMAKE_SOURCE_DIR}/src/main.zig" |
| 554 | 554 | "${CMAKE_SOURCE_DIR}/src/mingw.zig" |
src/Compilation.zig+1-1| ... | ... | @@ -2106,7 +2106,7 @@ pub fn addCCArgs( |
| 2106 | 2106 | try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS"); |
| 2107 | 2107 | } |
| 2108 | 2108 | |
| 2109 | const llvm_triple = try @import("codegen/llvm.zig").targetTriple(arena, target); | |
| 2109 | const llvm_triple = try @import("llvm_backend.zig").targetTriple(arena, target); | |
| 2110 | 2110 | try argv.appendSlice(&[_][]const u8{ "-target", llvm_triple }); |
| 2111 | 2111 | |
| 2112 | 2112 | switch (ext) { |
src/codegen/llvm.zig deleted-125| ... | ... | @@ -1,125 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const Allocator = std.mem.Allocator; | |
| 3 | ||
| 4 | pub fn targetTriple(allocator: *Allocator, target: std.Target) ![]u8 { | |
| 5 | const llvm_arch = switch (target.cpu.arch) { | |
| 6 | .arm => "arm", | |
| 7 | .armeb => "armeb", | |
| 8 | .aarch64 => "aarch64", | |
| 9 | .aarch64_be => "aarch64_be", | |
| 10 | .aarch64_32 => "aarch64_32", | |
| 11 | .arc => "arc", | |
| 12 | .avr => "avr", | |
| 13 | .bpfel => "bpfel", | |
| 14 | .bpfeb => "bpfeb", | |
| 15 | .hexagon => "hexagon", | |
| 16 | .mips => "mips", | |
| 17 | .mipsel => "mipsel", | |
| 18 | .mips64 => "mips64", | |
| 19 | .mips64el => "mips64el", | |
| 20 | .msp430 => "msp430", | |
| 21 | .powerpc => "powerpc", | |
| 22 | .powerpc64 => "powerpc64", | |
| 23 | .powerpc64le => "powerpc64le", | |
| 24 | .r600 => "r600", | |
| 25 | .amdgcn => "amdgcn", | |
| 26 | .riscv32 => "riscv32", | |
| 27 | .riscv64 => "riscv64", | |
| 28 | .sparc => "sparc", | |
| 29 | .sparcv9 => "sparcv9", | |
| 30 | .sparcel => "sparcel", | |
| 31 | .s390x => "s390x", | |
| 32 | .tce => "tce", | |
| 33 | .tcele => "tcele", | |
| 34 | .thumb => "thumb", | |
| 35 | .thumbeb => "thumbeb", | |
| 36 | .i386 => "i386", | |
| 37 | .x86_64 => "x86_64", | |
| 38 | .xcore => "xcore", | |
| 39 | .nvptx => "nvptx", | |
| 40 | .nvptx64 => "nvptx64", | |
| 41 | .le32 => "le32", | |
| 42 | .le64 => "le64", | |
| 43 | .amdil => "amdil", | |
| 44 | .amdil64 => "amdil64", | |
| 45 | .hsail => "hsail", | |
| 46 | .hsail64 => "hsail64", | |
| 47 | .spir => "spir", | |
| 48 | .spir64 => "spir64", | |
| 49 | .kalimba => "kalimba", | |
| 50 | .shave => "shave", | |
| 51 | .lanai => "lanai", | |
| 52 | .wasm32 => "wasm32", | |
| 53 | .wasm64 => "wasm64", | |
| 54 | .renderscript32 => "renderscript32", | |
| 55 | .renderscript64 => "renderscript64", | |
| 56 | .ve => "ve", | |
| 57 | .spu_2 => return error.LLVMBackendDoesNotSupportSPUMarkII, | |
| 58 | }; | |
| 59 | // TODO Add a sub-arch for some architectures depending on CPU features. | |
| 60 | ||
| 61 | const llvm_os = switch (target.os.tag) { | |
| 62 | .freestanding => "unknown", | |
| 63 | .ananas => "ananas", | |
| 64 | .cloudabi => "cloudabi", | |
| 65 | .dragonfly => "dragonfly", | |
| 66 | .freebsd => "freebsd", | |
| 67 | .fuchsia => "fuchsia", | |
| 68 | .ios => "ios", | |
| 69 | .kfreebsd => "kfreebsd", | |
| 70 | .linux => "linux", | |
| 71 | .lv2 => "lv2", | |
| 72 | .macos => "macosx", | |
| 73 | .netbsd => "netbsd", | |
| 74 | .openbsd => "openbsd", | |
| 75 | .solaris => "solaris", | |
| 76 | .windows => "windows", | |
| 77 | .haiku => "haiku", | |
| 78 | .minix => "minix", | |
| 79 | .rtems => "rtems", | |
| 80 | .nacl => "nacl", | |
| 81 | .cnk => "cnk", | |
| 82 | .aix => "aix", | |
| 83 | .cuda => "cuda", | |
| 84 | .nvcl => "nvcl", | |
| 85 | .amdhsa => "amdhsa", | |
| 86 | .ps4 => "ps4", | |
| 87 | .elfiamcu => "elfiamcu", | |
| 88 | .tvos => "tvos", | |
| 89 | .watchos => "watchos", | |
| 90 | .mesa3d => "mesa3d", | |
| 91 | .contiki => "contiki", | |
| 92 | .amdpal => "amdpal", | |
| 93 | .hermit => "hermit", | |
| 94 | .hurd => "hurd", | |
| 95 | .wasi => "wasi", | |
| 96 | .emscripten => "emscripten", | |
| 97 | .uefi => "windows", | |
| 98 | .other => "unknown", | |
| 99 | }; | |
| 100 | ||
| 101 | const llvm_abi = switch (target.abi) { | |
| 102 | .none => "unknown", | |
| 103 | .gnu => "gnu", | |
| 104 | .gnuabin32 => "gnuabin32", | |
| 105 | .gnuabi64 => "gnuabi64", | |
| 106 | .gnueabi => "gnueabi", | |
| 107 | .gnueabihf => "gnueabihf", | |
| 108 | .gnux32 => "gnux32", | |
| 109 | .code16 => "code16", | |
| 110 | .eabi => "eabi", | |
| 111 | .eabihf => "eabihf", | |
| 112 | .android => "android", | |
| 113 | .musl => "musl", | |
| 114 | .musleabi => "musleabi", | |
| 115 | .musleabihf => "musleabihf", | |
| 116 | .msvc => "msvc", | |
| 117 | .itanium => "itanium", | |
| 118 | .cygnus => "cygnus", | |
| 119 | .coreclr => "coreclr", | |
| 120 | .simulator => "simulator", | |
| 121 | .macabi => "macabi", | |
| 122 | }; | |
| 123 | ||
| 124 | return std.fmt.allocPrint(allocator, "{}-unknown-{}-{}", .{ llvm_arch, llvm_os, llvm_abi }); | |
| 125 | } |
src/link/Elf.zig+43-2| ... | ... | @@ -24,6 +24,7 @@ const build_options = @import("build_options"); |
| 24 | 24 | const target_util = @import("../target.zig"); |
| 25 | 25 | const glibc = @import("../glibc.zig"); |
| 26 | 26 | const Cache = @import("../Cache.zig"); |
| 27 | const llvm_backend = @import("../llvm_backend.zig"); | |
| 27 | 28 | |
| 28 | 29 | const default_entry_addr = 0x8000000; |
| 29 | 30 | |
| ... | ... | @@ -33,6 +34,9 @@ base: File, |
| 33 | 34 | |
| 34 | 35 | ptr_width: PtrWidth, |
| 35 | 36 | |
| 37 | /// If this is not null, an object file is created by LLVM and linked with LLD afterwards. | |
| 38 | llvm_ir_module: ?*llvm_backend.LLVMIRModule = null, | |
| 39 | ||
| 36 | 40 | /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. |
| 37 | 41 | /// Same order as in the file. |
| 38 | 42 | sections: std.ArrayListUnmanaged(elf.Elf64_Shdr) = std.ArrayListUnmanaged(elf.Elf64_Shdr){}, |
| ... | ... | @@ -224,7 +228,13 @@ pub const SrcFn = struct { |
| 224 | 228 | pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*Elf { |
| 225 | 229 | assert(options.object_format == .elf); |
| 226 | 230 | |
| 227 | if (options.use_llvm) return error.LLVMBackendUnimplementedForELF; // TODO | |
| 231 | if (options.use_llvm) { | |
| 232 | const self = try createEmpty(allocator, options); | |
| 233 | errdefer self.base.destroy(); | |
| 234 | ||
| 235 | self.llvm_ir_module = try llvm_backend.LLVMIRModule.create(allocator, sub_path, options); | |
| 236 | return self; | |
| 237 | } | |
| 228 | 238 | |
| 229 | 239 | const file = try options.emit.?.directory.handle.createFile(sub_path, .{ |
| 230 | 240 | .truncate = false, |
| ... | ... | @@ -288,6 +298,7 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Elf { |
| 288 | 298 | } |
| 289 | 299 | |
| 290 | 300 | pub fn deinit(self: *Elf) void { |
| 301 | if (self.llvm_ir_module) |ir_module| ir_module.deinit(self.base.allocator); | |
| 291 | 302 | self.sections.deinit(self.base.allocator); |
| 292 | 303 | self.program_headers.deinit(self.base.allocator); |
| 293 | 304 | self.shstrtab.deinit(self.base.allocator); |
| ... | ... | @@ -423,6 +434,8 @@ fn updateString(self: *Elf, old_str_off: u32, new_name: []const u8) !u32 { |
| 423 | 434 | } |
| 424 | 435 | |
| 425 | 436 | pub fn populateMissingMetadata(self: *Elf) !void { |
| 437 | if (self.llvm_ir_module) |_| return; | |
| 438 | ||
| 426 | 439 | const small_ptr = switch (self.ptr_width) { |
| 427 | 440 | .p32 => true, |
| 428 | 441 | .p64 => false, |
| ... | ... | @@ -727,6 +740,11 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 727 | 740 | const tracy = trace(@src()); |
| 728 | 741 | defer tracy.end(); |
| 729 | 742 | |
| 743 | if (self.llvm_ir_module) |llvm_ir_module| { | |
| 744 | try llvm_ir_module.flushModule(comp); | |
| 745 | return; | |
| 746 | } | |
| 747 | ||
| 730 | 748 | // TODO This linker code currently assumes there is only 1 compilation unit and it corresponds to the |
| 731 | 749 | // Zig source code. |
| 732 | 750 | const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; |
| ... | ... | @@ -1261,6 +1279,9 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1261 | 1279 | const stack_size = self.base.options.stack_size_override orelse 16777216; |
| 1262 | 1280 | const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os; |
| 1263 | 1281 | const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt) blk: { |
| 1282 | // TODO: remove when stage2 can build compiler_rt.zig | |
| 1283 | if (!build_options.is_stage1) break :blk null; | |
| 1284 | ||
| 1264 | 1285 | if (is_exe_or_dyn_lib) { |
| 1265 | 1286 | break :blk comp.compiler_rt_static_lib.?.full_object_path; |
| 1266 | 1287 | } else { |
| ... | ... | @@ -1552,7 +1573,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1552 | 1573 | } |
| 1553 | 1574 | |
| 1554 | 1575 | // libc |
| 1555 | if (is_exe_or_dyn_lib and !self.base.options.skip_linker_dependencies and !self.base.options.link_libc) { | |
| 1576 | // TODO: enable when stage2 can build c.zig | |
| 1577 | if (is_exe_or_dyn_lib and | |
| 1578 | !self.base.options.skip_linker_dependencies and | |
| 1579 | !self.base.options.link_libc and | |
| 1580 | build_options.is_stage1) | |
| 1581 | { | |
| 1556 | 1582 | try argv.append(comp.libc_static_lib.?.full_object_path); |
| 1557 | 1583 | } |
| 1558 | 1584 | |
| ... | ... | @@ -2046,6 +2072,8 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al |
| 2046 | 2072 | } |
| 2047 | 2073 | |
| 2048 | 2074 | pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void { |
| 2075 | if (self.llvm_ir_module) |_| return; | |
| 2076 | ||
| 2049 | 2077 | if (decl.link.elf.local_sym_index != 0) return; |
| 2050 | 2078 | |
| 2051 | 2079 | try self.local_symbols.ensureCapacity(self.base.allocator, self.local_symbols.items.len + 1); |
| ... | ... | @@ -2082,6 +2110,8 @@ pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void { |
| 2082 | 2110 | } |
| 2083 | 2111 | |
| 2084 | 2112 | pub fn freeDecl(self: *Elf, decl: *Module.Decl) void { |
| 2113 | if (self.llvm_ir_module) |_| return; | |
| 2114 | ||
| 2085 | 2115 | // Appending to free lists is allowed to fail because the free lists are heuristics based anyway. |
| 2086 | 2116 | self.freeTextBlock(&decl.link.elf); |
| 2087 | 2117 | if (decl.link.elf.local_sym_index != 0) { |
| ... | ... | @@ -2119,6 +2149,11 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { |
| 2119 | 2149 | const tracy = trace(@src()); |
| 2120 | 2150 | defer tracy.end(); |
| 2121 | 2151 | |
| 2152 | if (self.llvm_ir_module) |llvm_ir_module| { | |
| 2153 | try llvm_ir_module.updateDecl(module, decl); | |
| 2154 | return; | |
| 2155 | } | |
| 2156 | ||
| 2122 | 2157 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 2123 | 2158 | defer code_buffer.deinit(); |
| 2124 | 2159 | |
| ... | ... | @@ -2594,6 +2629,8 @@ pub fn updateDeclExports( |
| 2594 | 2629 | decl: *const Module.Decl, |
| 2595 | 2630 | exports: []const *Module.Export, |
| 2596 | 2631 | ) !void { |
| 2632 | if (self.llvm_ir_module) |_| return; | |
| 2633 | ||
| 2597 | 2634 | const tracy = trace(@src()); |
| 2598 | 2635 | defer tracy.end(); |
| 2599 | 2636 | |
| ... | ... | @@ -2667,6 +2704,8 @@ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Dec |
| 2667 | 2704 | const tracy = trace(@src()); |
| 2668 | 2705 | defer tracy.end(); |
| 2669 | 2706 | |
| 2707 | if (self.llvm_ir_module) |_| return; | |
| 2708 | ||
| 2670 | 2709 | const container_scope = decl.scope.cast(Module.Scope.Container).?; |
| 2671 | 2710 | const tree = container_scope.file_scope.contents.tree; |
| 2672 | 2711 | const file_ast_decls = tree.root_node.decls(); |
| ... | ... | @@ -2685,6 +2724,8 @@ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Dec |
| 2685 | 2724 | } |
| 2686 | 2725 | |
| 2687 | 2726 | pub fn deleteExport(self: *Elf, exp: Export) void { |
| 2727 | if (self.llvm_ir_module) |_| return; | |
| 2728 | ||
| 2688 | 2729 | const sym_index = exp.sym_index orelse return; |
| 2689 | 2730 | self.global_symbol_free_list.append(self.base.allocator, sym_index) catch {}; |
| 2690 | 2731 | self.global_symbols.items[sym_index].st_info = 0; |
src/llvm_backend.zig created+410| ... | ... | @@ -0,0 +1,410 @@ |
| 1 | const std = @import("std"); | |
| 2 | const Allocator = std.mem.Allocator; | |
| 3 | const Compilation = @import("Compilation.zig"); | |
| 4 | const llvm = @import("llvm_bindings.zig"); | |
| 5 | const link = @import("link.zig"); | |
| 6 | ||
| 7 | const Module = @import("Module.zig"); | |
| 8 | const TypedValue = @import("TypedValue.zig"); | |
| 9 | const ir = @import("ir.zig"); | |
| 10 | const Inst = ir.Inst; | |
| 11 | ||
| 12 | const Value = @import("value.zig").Value; | |
| 13 | const Type = @import("type.zig").Type; | |
| 14 | ||
| 15 | pub fn targetTriple(allocator: *Allocator, target: std.Target) ![:0]u8 { | |
| 16 | const llvm_arch = switch (target.cpu.arch) { | |
| 17 | .arm => "arm", | |
| 18 | .armeb => "armeb", | |
| 19 | .aarch64 => "aarch64", | |
| 20 | .aarch64_be => "aarch64_be", | |
| 21 | .aarch64_32 => "aarch64_32", | |
| 22 | .arc => "arc", | |
| 23 | .avr => "avr", | |
| 24 | .bpfel => "bpfel", | |
| 25 | .bpfeb => "bpfeb", | |
| 26 | .hexagon => "hexagon", | |
| 27 | .mips => "mips", | |
| 28 | .mipsel => "mipsel", | |
| 29 | .mips64 => "mips64", | |
| 30 | .mips64el => "mips64el", | |
| 31 | .msp430 => "msp430", | |
| 32 | .powerpc => "powerpc", | |
| 33 | .powerpc64 => "powerpc64", | |
| 34 | .powerpc64le => "powerpc64le", | |
| 35 | .r600 => "r600", | |
| 36 | .amdgcn => "amdgcn", | |
| 37 | .riscv32 => "riscv32", | |
| 38 | .riscv64 => "riscv64", | |
| 39 | .sparc => "sparc", | |
| 40 | .sparcv9 => "sparcv9", | |
| 41 | .sparcel => "sparcel", | |
| 42 | .s390x => "s390x", | |
| 43 | .tce => "tce", | |
| 44 | .tcele => "tcele", | |
| 45 | .thumb => "thumb", | |
| 46 | .thumbeb => "thumbeb", | |
| 47 | .i386 => "i386", | |
| 48 | .x86_64 => "x86_64", | |
| 49 | .xcore => "xcore", | |
| 50 | .nvptx => "nvptx", | |
| 51 | .nvptx64 => "nvptx64", | |
| 52 | .le32 => "le32", | |
| 53 | .le64 => "le64", | |
| 54 | .amdil => "amdil", | |
| 55 | .amdil64 => "amdil64", | |
| 56 | .hsail => "hsail", | |
| 57 | .hsail64 => "hsail64", | |
| 58 | .spir => "spir", | |
| 59 | .spir64 => "spir64", | |
| 60 | .kalimba => "kalimba", | |
| 61 | .shave => "shave", | |
| 62 | .lanai => "lanai", | |
| 63 | .wasm32 => "wasm32", | |
| 64 | .wasm64 => "wasm64", | |
| 65 | .renderscript32 => "renderscript32", | |
| 66 | .renderscript64 => "renderscript64", | |
| 67 | .ve => "ve", | |
| 68 | .spu_2 => return error.LLVMBackendDoesNotSupportSPUMarkII, | |
| 69 | }; | |
| 70 | // TODO Add a sub-arch for some architectures depending on CPU features. | |
| 71 | ||
| 72 | const llvm_os = switch (target.os.tag) { | |
| 73 | .freestanding => "unknown", | |
| 74 | .ananas => "ananas", | |
| 75 | .cloudabi => "cloudabi", | |
| 76 | .dragonfly => "dragonfly", | |
| 77 | .freebsd => "freebsd", | |
| 78 | .fuchsia => "fuchsia", | |
| 79 | .ios => "ios", | |
| 80 | .kfreebsd => "kfreebsd", | |
| 81 | .linux => "linux", | |
| 82 | .lv2 => "lv2", | |
| 83 | .macos => "macosx", | |
| 84 | .netbsd => "netbsd", | |
| 85 | .openbsd => "openbsd", | |
| 86 | .solaris => "solaris", | |
| 87 | .windows => "windows", | |
| 88 | .haiku => "haiku", | |
| 89 | .minix => "minix", | |
| 90 | .rtems => "rtems", | |
| 91 | .nacl => "nacl", | |
| 92 | .cnk => "cnk", | |
| 93 | .aix => "aix", | |
| 94 | .cuda => "cuda", | |
| 95 | .nvcl => "nvcl", | |
| 96 | .amdhsa => "amdhsa", | |
| 97 | .ps4 => "ps4", | |
| 98 | .elfiamcu => "elfiamcu", | |
| 99 | .tvos => "tvos", | |
| 100 | .watchos => "watchos", | |
| 101 | .mesa3d => "mesa3d", | |
| 102 | .contiki => "contiki", | |
| 103 | .amdpal => "amdpal", | |
| 104 | .hermit => "hermit", | |
| 105 | .hurd => "hurd", | |
| 106 | .wasi => "wasi", | |
| 107 | .emscripten => "emscripten", | |
| 108 | .uefi => "windows", | |
| 109 | .other => "unknown", | |
| 110 | }; | |
| 111 | ||
| 112 | const llvm_abi = switch (target.abi) { | |
| 113 | .none => "unknown", | |
| 114 | .gnu => "gnu", | |
| 115 | .gnuabin32 => "gnuabin32", | |
| 116 | .gnuabi64 => "gnuabi64", | |
| 117 | .gnueabi => "gnueabi", | |
| 118 | .gnueabihf => "gnueabihf", | |
| 119 | .gnux32 => "gnux32", | |
| 120 | .code16 => "code16", | |
| 121 | .eabi => "eabi", | |
| 122 | .eabihf => "eabihf", | |
| 123 | .android => "android", | |
| 124 | .musl => "musl", | |
| 125 | .musleabi => "musleabi", | |
| 126 | .musleabihf => "musleabihf", | |
| 127 | .msvc => "msvc", | |
| 128 | .itanium => "itanium", | |
| 129 | .cygnus => "cygnus", | |
| 130 | .coreclr => "coreclr", | |
| 131 | .simulator => "simulator", | |
| 132 | .macabi => "macabi", | |
| 133 | }; | |
| 134 | ||
| 135 | return std.fmt.allocPrintZ(allocator, "{}-unknown-{}-{}", .{ llvm_arch, llvm_os, llvm_abi }); | |
| 136 | } | |
| 137 | ||
| 138 | pub const LLVMIRModule = struct { | |
| 139 | llvm_module: *const llvm.ModuleRef, | |
| 140 | target_machine: *const llvm.TargetMachineRef, | |
| 141 | output_path: []const u8, | |
| 142 | ||
| 143 | gpa: *Allocator, | |
| 144 | err_msg: ?*Compilation.ErrorMsg = null, | |
| 145 | ||
| 146 | pub fn create(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*LLVMIRModule { | |
| 147 | const self = try allocator.create(LLVMIRModule); | |
| 148 | errdefer allocator.destroy(self); | |
| 149 | ||
| 150 | const gpa = options.module.?.gpa; | |
| 151 | ||
| 152 | initializeLLVMTargets(); | |
| 153 | ||
| 154 | const root_nameZ = try gpa.dupeZ(u8, options.root_name); | |
| 155 | defer gpa.free(root_nameZ); | |
| 156 | const llvm_module = llvm.ModuleRef.createWithName(root_nameZ.ptr); | |
| 157 | errdefer llvm_module.disposeModule(); | |
| 158 | ||
| 159 | const llvm_target_triple = try targetTriple(gpa, options.target); | |
| 160 | defer gpa.free(llvm_target_triple); | |
| 161 | ||
| 162 | var error_message: [*:0]const u8 = undefined; | |
| 163 | var target_ref: *const llvm.TargetRef = undefined; | |
| 164 | if (llvm.TargetRef.getTargetFromTriple(llvm_target_triple.ptr, &target_ref, &error_message)) { | |
| 165 | defer llvm.disposeMessage(error_message); | |
| 166 | ||
| 167 | const stderr = std.io.getStdErr().outStream(); | |
| 168 | try stderr.print( | |
| 169 | \\Zig is expecting LLVM to understand this target: '{s}' | |
| 170 | \\However LLVM responded with: "{s}" | |
| 171 | \\Zig is unable to continue. This is a bug in Zig: | |
| 172 | \\https://github.com/ziglang/zig/issues/438 | |
| 173 | \\ | |
| 174 | , | |
| 175 | .{ | |
| 176 | llvm_target_triple, | |
| 177 | error_message, | |
| 178 | }, | |
| 179 | ); | |
| 180 | return error.InvalidLLVMTriple; | |
| 181 | } | |
| 182 | ||
| 183 | const opt_level: llvm.CodeGenOptLevel = if (options.optimize_mode == .Debug) .None else .Aggressive; | |
| 184 | const target_machine = llvm.TargetMachineRef.createTargetMachine( | |
| 185 | target_ref, | |
| 186 | llvm_target_triple.ptr, | |
| 187 | "", | |
| 188 | "", | |
| 189 | opt_level, | |
| 190 | .Static, | |
| 191 | .Default, | |
| 192 | ); | |
| 193 | errdefer target_machine.disposeTargetMachine(); | |
| 194 | ||
| 195 | self.* = .{ | |
| 196 | .llvm_module = llvm_module, | |
| 197 | .target_machine = target_machine, | |
| 198 | .output_path = sub_path, | |
| 199 | .gpa = gpa, | |
| 200 | }; | |
| 201 | return self; | |
| 202 | } | |
| 203 | ||
| 204 | pub fn deinit(self: *LLVMIRModule, allocator: *Allocator) void { | |
| 205 | self.llvm_module.disposeModule(); | |
| 206 | self.target_machine.disposeTargetMachine(); | |
| 207 | allocator.destroy(self); | |
| 208 | } | |
| 209 | ||
| 210 | fn initializeLLVMTargets() void { | |
| 211 | llvm.initializeAllTargets(); | |
| 212 | llvm.initializeAllTargetInfos(); | |
| 213 | llvm.initializeAllTargetMCs(); | |
| 214 | llvm.initializeAllAsmPrinters(); | |
| 215 | llvm.initializeAllAsmParsers(); | |
| 216 | } | |
| 217 | ||
| 218 | pub fn flushModule(self: *LLVMIRModule, comp: *Compilation) !void { | |
| 219 | { | |
| 220 | var error_message: [*:0]const u8 = undefined; | |
| 221 | // verifyModule always allocs the error_message even if there is no error | |
| 222 | defer llvm.disposeMessage(error_message); | |
| 223 | ||
| 224 | if (self.llvm_module.verifyModule(.ReturnStatus, &error_message)) { | |
| 225 | const stderr = std.io.getStdErr().outStream(); | |
| 226 | try stderr.print("broken LLVM module found: {s}\nThis is a bug in the Zig compiler.", .{error_message}); | |
| 227 | return error.BrokenLLVMModule; | |
| 228 | } | |
| 229 | } | |
| 230 | ||
| 231 | if (comp.verbose_llvm_ir) { | |
| 232 | const dump = self.llvm_module.printToString(); | |
| 233 | defer llvm.disposeMessage(dump); | |
| 234 | ||
| 235 | const stderr = std.io.getStdErr().outStream(); | |
| 236 | try stderr.writeAll(std.mem.spanZ(dump)); | |
| 237 | } | |
| 238 | ||
| 239 | const output_pathZ = try self.gpa.dupeZ(u8, self.output_path); | |
| 240 | defer self.gpa.free(output_pathZ); | |
| 241 | ||
| 242 | var error_message: [*:0]const u8 = undefined; | |
| 243 | // TODO: where to put the output object, zig-cache something? | |
| 244 | // TODO: caching? | |
| 245 | if (self.target_machine.emitToFile( | |
| 246 | self.llvm_module, | |
| 247 | output_pathZ.ptr, | |
| 248 | .ObjectFile, | |
| 249 | &error_message, | |
| 250 | )) { | |
| 251 | defer llvm.disposeMessage(error_message); | |
| 252 | ||
| 253 | const stderr = std.io.getStdErr().outStream(); | |
| 254 | try stderr.print("LLVM failed to emit file: {s}\n", .{error_message}); | |
| 255 | return error.FailedToEmit; | |
| 256 | } | |
| 257 | } | |
| 258 | ||
| 259 | pub fn updateDecl(self: *LLVMIRModule, module: *Module, decl: *Module.Decl) !void { | |
| 260 | const typed_value = decl.typed_value.most_recent.typed_value; | |
| 261 | self.generate(module, typed_value, decl.src()) catch |err| switch (err) { | |
| 262 | error.CodegenFail => { | |
| 263 | decl.analysis = .codegen_failure; | |
| 264 | try module.failed_decls.put(module.gpa, decl, self.err_msg.?); | |
| 265 | return; | |
| 266 | }, | |
| 267 | else => |e| return e, | |
| 268 | }; | |
| 269 | } | |
| 270 | ||
| 271 | fn generate(self: *LLVMIRModule, module: *Module, typed_value: TypedValue, src: usize) !void { | |
| 272 | switch (typed_value.ty.zigTypeTag()) { | |
| 273 | .Fn => { | |
| 274 | const func = typed_value.val.cast(Value.Payload.Function).?.func; | |
| 275 | ||
| 276 | var codegen = CodeGen{ | |
| 277 | .module = module, | |
| 278 | .llvm_module = self.llvm_module, | |
| 279 | .builder = llvm.BuilderRef.createBuilder(), | |
| 280 | }; | |
| 281 | defer codegen.builder.disposeBuilder(); | |
| 282 | ||
| 283 | const llvm_func = try codegen.resolveLLVMFunction(func); | |
| 284 | ||
| 285 | // We remove all the basic blocks of a function to support incremental | |
| 286 | // compilation! | |
| 287 | // TODO: remove all basic blocks if functions can have more than one | |
| 288 | if (llvm_func.getFirstBasicBlock()) |bb| { | |
| 289 | bb.deleteBasicBlock(); | |
| 290 | } | |
| 291 | ||
| 292 | const entry_block = llvm_func.appendBasicBlock("Entry"); | |
| 293 | codegen.builder.positionBuilderAtEnd(entry_block); | |
| 294 | ||
| 295 | const instructions = func.analysis.success.instructions; | |
| 296 | for (instructions) |inst| { | |
| 297 | switch (inst.tag) { | |
| 298 | .breakpoint => try codegen.generateBreakpoint(inst.castTag(.breakpoint).?), | |
| 299 | .call => try codegen.generateCall(inst.castTag(.call).?), | |
| 300 | .unreach => codegen.generateUnreach(inst.castTag(.unreach).?), | |
| 301 | .retvoid => codegen.generateRetVoid(inst.castTag(.retvoid).?), | |
| 302 | .dbg_stmt => { | |
| 303 | // TODO: implement debug info | |
| 304 | }, | |
| 305 | else => |tag| return self.fail(src, "TODO implement LLVM codegen for Zir instruction: {}", .{tag}), | |
| 306 | } | |
| 307 | } | |
| 308 | }, | |
| 309 | else => |ty| return self.fail(src, "TODO implement LLVM codegen for top-level decl type: {}", .{ty}), | |
| 310 | } | |
| 311 | } | |
| 312 | ||
| 313 | pub fn fail(self: *LLVMIRModule, src: usize, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { | |
| 314 | @setCold(true); | |
| 315 | std.debug.assert(self.err_msg == null); | |
| 316 | self.err_msg = try Compilation.ErrorMsg.create(self.gpa, src, format, args); | |
| 317 | return error.CodegenFail; | |
| 318 | } | |
| 319 | }; | |
| 320 | ||
| 321 | const CodeGen = struct { | |
| 322 | module: *Module, | |
| 323 | llvm_module: *const llvm.ModuleRef, | |
| 324 | builder: *const llvm.BuilderRef, | |
| 325 | ||
| 326 | fn generateCall(codegen: *CodeGen, inst: *Inst.Call) !void { | |
| 327 | if (inst.func.cast(Inst.Constant)) |func_inst| { | |
| 328 | if (func_inst.val.cast(Value.Payload.Function)) |func_val| { | |
| 329 | const func = func_val.func; | |
| 330 | const zig_fn_type = func.owner_decl.typed_value.most_recent.typed_value.ty; | |
| 331 | const llvm_fn = try codegen.resolveLLVMFunction(func); | |
| 332 | ||
| 333 | // TODO: handle more arguments, inst.args | |
| 334 | ||
| 335 | // TODO: LLVMBuildCall2 handles opaque function pointers, according to llvm docs | |
| 336 | // Do we need that? | |
| 337 | const call = codegen.builder.buildCall(llvm_fn, null, 0, ""); | |
| 338 | ||
| 339 | if (zig_fn_type.fnReturnType().zigTypeTag() == .NoReturn) { | |
| 340 | _ = codegen.builder.buildUnreachable(); | |
| 341 | } | |
| 342 | } | |
| 343 | } | |
| 344 | } | |
| 345 | ||
| 346 | fn generateRetVoid(codegen: *CodeGen, inst: *Inst.NoOp) void { | |
| 347 | _ = codegen.builder.buildRetVoid(); | |
| 348 | } | |
| 349 | ||
| 350 | fn generateUnreach(codegen: *CodeGen, inst: *Inst.NoOp) void { | |
| 351 | _ = codegen.builder.buildUnreachable(); | |
| 352 | } | |
| 353 | ||
| 354 | fn generateBreakpoint(codegen: *CodeGen, inst: *Inst.NoOp) !void { | |
| 355 | // TODO: Store this function somewhere such that we dont have to add it again | |
| 356 | const fn_type = llvm.TypeRef.functionType(llvm.voidType(), null, 0, false); | |
| 357 | const func = codegen.llvm_module.addFunction("llvm.debugtrap", fn_type); | |
| 358 | // TODO: add assertion: LLVMGetIntrinsicID | |
| 359 | _ = codegen.builder.buildCall(func, null, 0, ""); | |
| 360 | } | |
| 361 | ||
| 362 | /// If the llvm function does not exist, create it | |
| 363 | fn resolveLLVMFunction(codegen: *CodeGen, func: *Module.Fn) !*const llvm.ValueRef { | |
| 364 | // TODO: do we want to store this in our own datastructure? | |
| 365 | if (codegen.llvm_module.getNamedFunction(func.owner_decl.name)) |llvm_fn| return llvm_fn; | |
| 366 | ||
| 367 | const zig_fn_type = func.owner_decl.typed_value.most_recent.typed_value.ty; | |
| 368 | const return_type = zig_fn_type.fnReturnType(); | |
| 369 | ||
| 370 | const fn_param_len = zig_fn_type.fnParamLen(); | |
| 371 | ||
| 372 | const fn_param_types = try codegen.module.gpa.alloc(Type, fn_param_len); | |
| 373 | defer codegen.module.gpa.free(fn_param_types); | |
| 374 | zig_fn_type.fnParamTypes(fn_param_types); | |
| 375 | ||
| 376 | const llvm_param = try codegen.module.gpa.alloc(*const llvm.TypeRef, fn_param_len); | |
| 377 | defer codegen.module.gpa.free(llvm_param); | |
| 378 | ||
| 379 | for (fn_param_types) |fn_param, i| { | |
| 380 | llvm_param[i] = codegen.getLLVMType(fn_param); | |
| 381 | } | |
| 382 | ||
| 383 | const fn_type = llvm.TypeRef.functionType( | |
| 384 | codegen.getLLVMType(return_type), | |
| 385 | if (fn_param_len == 0) null else llvm_param.ptr, | |
| 386 | @intCast(c_uint, fn_param_len), | |
| 387 | false, | |
| 388 | ); | |
| 389 | const llvm_fn = codegen.llvm_module.addFunction(func.owner_decl.name, fn_type); | |
| 390 | ||
| 391 | if (return_type.zigTypeTag() == .NoReturn) { | |
| 392 | llvm_fn.addFnAttr("noreturn"); | |
| 393 | } | |
| 394 | ||
| 395 | return llvm_fn; | |
| 396 | } | |
| 397 | ||
| 398 | fn getLLVMType(codegen: *CodeGen, t: Type) *const llvm.TypeRef { | |
| 399 | switch (t.zigTypeTag()) { | |
| 400 | .Void => return llvm.voidType(), | |
| 401 | .NoReturn => return llvm.voidType(), | |
| 402 | .Int => { | |
| 403 | const info = t.intInfo(codegen.module.getTarget()); | |
| 404 | return llvm.intType(info.bits); | |
| 405 | }, | |
| 406 | .Bool => return llvm.intType(1), | |
| 407 | else => unreachable, | |
| 408 | } | |
| 409 | } | |
| 410 | }; |
src/llvm_bindings.zig+358| ... | ... | @@ -1,6 +1,364 @@ |
| 1 | 1 | //! We do this instead of @cImport because the self-hosted compiler is easier |
| 2 | 2 | //! to bootstrap if it does not depend on translate-c. |
| 3 | 3 | |
| 4 | const std = @import("std"); | |
| 5 | const assert = std.debug.assert; | |
| 6 | ||
| 7 | const LLVMBool = bool; | |
| 8 | pub const LLVMAttributeIndex = c_uint; | |
| 9 | ||
| 10 | pub const ValueRef = opaque { | |
| 11 | pub const addAttributeAtIndex = LLVMAddAttributeAtIndex; | |
| 12 | extern fn LLVMAddAttributeAtIndex(*const ValueRef, Idx: LLVMAttributeIndex, A: *const AttributeRef) void; | |
| 13 | ||
| 14 | pub const appendBasicBlock = LLVMAppendBasicBlock; | |
| 15 | extern fn LLVMAppendBasicBlock(Fn: *const ValueRef, Name: [*:0]const u8) *const BasicBlockRef; | |
| 16 | ||
| 17 | pub const getFirstBasicBlock = LLVMGetFirstBasicBlock; | |
| 18 | extern fn LLVMGetFirstBasicBlock(Fn: *const ValueRef) ?*const BasicBlockRef; | |
| 19 | ||
| 20 | // Helper functions | |
| 21 | // TODO: Do we want to put these functions here? It allows for convienient function calls | |
| 22 | // on ValueRef: llvm_fn.addFnAttr("noreturn") | |
| 23 | fn addAttr(val: *const ValueRef, index: LLVMAttributeIndex, name: []const u8) void { | |
| 24 | const kind_id = getEnumAttributeKindForName(name.ptr, name.len); | |
| 25 | assert(kind_id != 0); | |
| 26 | const llvm_attr = ContextRef.getGlobal().createEnumAttribute(kind_id, 0); | |
| 27 | val.addAttributeAtIndex(index, llvm_attr); | |
| 28 | } | |
| 29 | ||
| 30 | pub fn addFnAttr(val: *const ValueRef, attr_name: []const u8) void { | |
| 31 | // TODO: improve this API, `addAttr(-1, attr_name)` | |
| 32 | val.addAttr(std.math.maxInt(LLVMAttributeIndex), attr_name); | |
| 33 | } | |
| 34 | }; | |
| 35 | ||
| 36 | pub const TypeRef = opaque { | |
| 37 | pub const functionType = LLVMFunctionType; | |
| 38 | extern fn LLVMFunctionType(ReturnType: *const TypeRef, ParamTypes: ?[*]*const TypeRef, ParamCount: c_uint, IsVarArg: LLVMBool) *const TypeRef; | |
| 39 | }; | |
| 40 | ||
| 41 | pub const ModuleRef = opaque { | |
| 42 | pub const createWithName = LLVMModuleCreateWithName; | |
| 43 | extern fn LLVMModuleCreateWithName(ModuleID: [*:0]const u8) *const ModuleRef; | |
| 44 | ||
| 45 | pub const disposeModule = LLVMDisposeModule; | |
| 46 | extern fn LLVMDisposeModule(*const ModuleRef) void; | |
| 47 | ||
| 48 | pub const verifyModule = LLVMVerifyModule; | |
| 49 | extern fn LLVMVerifyModule(*const ModuleRef, Action: VerifierFailureAction, OutMessage: *[*:0]const u8) LLVMBool; | |
| 50 | ||
| 51 | pub const addFunction = LLVMAddFunction; | |
| 52 | extern fn LLVMAddFunction(*const ModuleRef, Name: [*:0]const u8, FunctionTy: *const TypeRef) *const ValueRef; | |
| 53 | ||
| 54 | pub const getNamedFunction = LLVMGetNamedFunction; | |
| 55 | extern fn LLVMGetNamedFunction(*const ModuleRef, Name: [*:0]const u8) ?*const ValueRef; | |
| 56 | ||
| 57 | pub const printToString = LLVMPrintModuleToString; | |
| 58 | extern fn LLVMPrintModuleToString(*const ModuleRef) [*:0]const u8; | |
| 59 | }; | |
| 60 | ||
| 61 | pub const disposeMessage = LLVMDisposeMessage; | |
| 62 | extern fn LLVMDisposeMessage(Message: [*:0]const u8) void; | |
| 63 | ||
| 64 | pub const VerifierFailureAction = extern enum { | |
| 65 | AbortProcess, | |
| 66 | PrintMessage, | |
| 67 | ReturnStatus, | |
| 68 | }; | |
| 69 | ||
| 70 | pub const voidType = LLVMVoidType; | |
| 71 | extern fn LLVMVoidType() *const TypeRef; | |
| 72 | ||
| 73 | pub const getEnumAttributeKindForName = LLVMGetEnumAttributeKindForName; | |
| 74 | extern fn LLVMGetEnumAttributeKindForName(Name: [*]const u8, SLen: usize) c_uint; | |
| 75 | ||
| 76 | pub const AttributeRef = opaque {}; | |
| 77 | ||
| 78 | pub const ContextRef = opaque { | |
| 79 | pub const createEnumAttribute = LLVMCreateEnumAttribute; | |
| 80 | extern fn LLVMCreateEnumAttribute(*const ContextRef, KindID: c_uint, Val: u64) *const AttributeRef; | |
| 81 | ||
| 82 | pub const getGlobal = LLVMGetGlobalContext; | |
| 83 | extern fn LLVMGetGlobalContext() *const ContextRef; | |
| 84 | }; | |
| 85 | ||
| 86 | pub const intType = LLVMIntType; | |
| 87 | extern fn LLVMIntType(NumBits: c_uint) *const TypeRef; | |
| 88 | ||
| 89 | pub const BuilderRef = opaque { | |
| 90 | pub const createBuilder = LLVMCreateBuilder; | |
| 91 | extern fn LLVMCreateBuilder() *const BuilderRef; | |
| 92 | ||
| 93 | pub const disposeBuilder = LLVMDisposeBuilder; | |
| 94 | extern fn LLVMDisposeBuilder(Builder: *const BuilderRef) void; | |
| 95 | ||
| 96 | pub const positionBuilderAtEnd = LLVMPositionBuilderAtEnd; | |
| 97 | extern fn LLVMPositionBuilderAtEnd(Builder: *const BuilderRef, Block: *const BasicBlockRef) void; | |
| 98 | ||
| 99 | pub const getInsertBlock = LLVMGetInsertBlock; | |
| 100 | extern fn LLVMGetInsertBlock(Builder: *const BuilderRef) *const BasicBlockRef; | |
| 101 | ||
| 102 | pub const buildCall = LLVMBuildCall; | |
| 103 | extern fn LLVMBuildCall(*const BuilderRef, Fn: *const ValueRef, Args: ?[*]*const ValueRef, NumArgs: c_uint, Name: [*:0]const u8) *const ValueRef; | |
| 104 | ||
| 105 | pub const buildCall2 = LLVMBuildCall2; | |
| 106 | extern fn LLVMBuildCall2(*const BuilderRef, *const TypeRef, Fn: *const ValueRef, Args: [*]*const ValueRef, NumArgs: c_uint, Name: [*:0]const u8) *const ValueRef; | |
| 107 | ||
| 108 | pub const buildRetVoid = LLVMBuildRetVoid; | |
| 109 | extern fn LLVMBuildRetVoid(*const BuilderRef) *const ValueRef; | |
| 110 | ||
| 111 | pub const buildUnreachable = LLVMBuildUnreachable; | |
| 112 | extern fn LLVMBuildUnreachable(*const BuilderRef) *const ValueRef; | |
| 113 | ||
| 114 | pub const buildAlloca = LLVMBuildAlloca; | |
| 115 | extern fn LLVMBuildAlloca(*const BuilderRef, Ty: *const TypeRef, Name: [*:0]const u8) *const ValueRef; | |
| 116 | }; | |
| 117 | ||
| 118 | pub const BasicBlockRef = opaque { | |
| 119 | pub const deleteBasicBlock = LLVMDeleteBasicBlock; | |
| 120 | extern fn LLVMDeleteBasicBlock(BB: *const BasicBlockRef) void; | |
| 121 | }; | |
| 122 | ||
| 123 | pub const TargetMachineRef = opaque { | |
| 124 | pub const createTargetMachine = LLVMCreateTargetMachine; | |
| 125 | extern fn LLVMCreateTargetMachine( | |
| 126 | T: *const TargetRef, | |
| 127 | Triple: [*:0]const u8, | |
| 128 | CPU: [*:0]const u8, | |
| 129 | Features: [*:0]const u8, | |
| 130 | Level: CodeGenOptLevel, | |
| 131 | Reloc: RelocMode, | |
| 132 | CodeModel: CodeMode, | |
| 133 | ) *const TargetMachineRef; | |
| 134 | ||
| 135 | pub const disposeTargetMachine = LLVMDisposeTargetMachine; | |
| 136 | extern fn LLVMDisposeTargetMachine(T: *const TargetMachineRef) void; | |
| 137 | ||
| 138 | pub const emitToFile = LLVMTargetMachineEmitToFile; | |
| 139 | extern fn LLVMTargetMachineEmitToFile(*const TargetMachineRef, M: *const ModuleRef, Filename: [*:0]const u8, codegen: CodeGenFileType, ErrorMessage: *[*:0]const u8) LLVMBool; | |
| 140 | }; | |
| 141 | ||
| 142 | pub const CodeMode = extern enum { | |
| 143 | Default, | |
| 144 | JITDefault, | |
| 145 | Tiny, | |
| 146 | Small, | |
| 147 | Kernel, | |
| 148 | Medium, | |
| 149 | Large, | |
| 150 | }; | |
| 151 | ||
| 152 | pub const CodeGenOptLevel = extern enum { | |
| 153 | None, | |
| 154 | Less, | |
| 155 | Default, | |
| 156 | Aggressive, | |
| 157 | }; | |
| 158 | ||
| 159 | pub const RelocMode = extern enum { | |
| 160 | Default, | |
| 161 | Static, | |
| 162 | PIC, | |
| 163 | DynamicNoPic, | |
| 164 | ROPI, | |
| 165 | RWPI, | |
| 166 | ROPI_RWPI, | |
| 167 | }; | |
| 168 | ||
| 169 | pub const CodeGenFileType = extern enum { | |
| 170 | AssemblyFile, | |
| 171 | ObjectFile, | |
| 172 | }; | |
| 173 | ||
| 174 | pub const TargetRef = opaque { | |
| 175 | pub const getTargetFromTriple = LLVMGetTargetFromTriple; | |
| 176 | extern fn LLVMGetTargetFromTriple(Triple: [*:0]const u8, T: **const TargetRef, ErrorMessage: *[*:0]const u8) LLVMBool; | |
| 177 | }; | |
| 178 | ||
| 179 | extern fn LLVMInitializeAArch64TargetInfo() void; | |
| 180 | extern fn LLVMInitializeAMDGPUTargetInfo() void; | |
| 181 | extern fn LLVMInitializeARMTargetInfo() void; | |
| 182 | extern fn LLVMInitializeAVRTargetInfo() void; | |
| 183 | extern fn LLVMInitializeBPFTargetInfo() void; | |
| 184 | extern fn LLVMInitializeHexagonTargetInfo() void; | |
| 185 | extern fn LLVMInitializeLanaiTargetInfo() void; | |
| 186 | extern fn LLVMInitializeMipsTargetInfo() void; | |
| 187 | extern fn LLVMInitializeMSP430TargetInfo() void; | |
| 188 | extern fn LLVMInitializeNVPTXTargetInfo() void; | |
| 189 | extern fn LLVMInitializePowerPCTargetInfo() void; | |
| 190 | extern fn LLVMInitializeRISCVTargetInfo() void; | |
| 191 | extern fn LLVMInitializeSparcTargetInfo() void; | |
| 192 | extern fn LLVMInitializeSystemZTargetInfo() void; | |
| 193 | extern fn LLVMInitializeWebAssemblyTargetInfo() void; | |
| 194 | extern fn LLVMInitializeX86TargetInfo() void; | |
| 195 | extern fn LLVMInitializeXCoreTargetInfo() void; | |
| 196 | extern fn LLVMInitializeAArch64Target() void; | |
| 197 | extern fn LLVMInitializeAMDGPUTarget() void; | |
| 198 | extern fn LLVMInitializeARMTarget() void; | |
| 199 | extern fn LLVMInitializeAVRTarget() void; | |
| 200 | extern fn LLVMInitializeBPFTarget() void; | |
| 201 | extern fn LLVMInitializeHexagonTarget() void; | |
| 202 | extern fn LLVMInitializeLanaiTarget() void; | |
| 203 | extern fn LLVMInitializeMipsTarget() void; | |
| 204 | extern fn LLVMInitializeMSP430Target() void; | |
| 205 | extern fn LLVMInitializeNVPTXTarget() void; | |
| 206 | extern fn LLVMInitializePowerPCTarget() void; | |
| 207 | extern fn LLVMInitializeRISCVTarget() void; | |
| 208 | extern fn LLVMInitializeSparcTarget() void; | |
| 209 | extern fn LLVMInitializeSystemZTarget() void; | |
| 210 | extern fn LLVMInitializeWebAssemblyTarget() void; | |
| 211 | extern fn LLVMInitializeX86Target() void; | |
| 212 | extern fn LLVMInitializeXCoreTarget() void; | |
| 213 | extern fn LLVMInitializeAArch64TargetMC() void; | |
| 214 | extern fn LLVMInitializeAMDGPUTargetMC() void; | |
| 215 | extern fn LLVMInitializeARMTargetMC() void; | |
| 216 | extern fn LLVMInitializeAVRTargetMC() void; | |
| 217 | extern fn LLVMInitializeBPFTargetMC() void; | |
| 218 | extern fn LLVMInitializeHexagonTargetMC() void; | |
| 219 | extern fn LLVMInitializeLanaiTargetMC() void; | |
| 220 | extern fn LLVMInitializeMipsTargetMC() void; | |
| 221 | extern fn LLVMInitializeMSP430TargetMC() void; | |
| 222 | extern fn LLVMInitializeNVPTXTargetMC() void; | |
| 223 | extern fn LLVMInitializePowerPCTargetMC() void; | |
| 224 | extern fn LLVMInitializeRISCVTargetMC() void; | |
| 225 | extern fn LLVMInitializeSparcTargetMC() void; | |
| 226 | extern fn LLVMInitializeSystemZTargetMC() void; | |
| 227 | extern fn LLVMInitializeWebAssemblyTargetMC() void; | |
| 228 | extern fn LLVMInitializeX86TargetMC() void; | |
| 229 | extern fn LLVMInitializeXCoreTargetMC() void; | |
| 230 | extern fn LLVMInitializeAArch64AsmPrinter() void; | |
| 231 | extern fn LLVMInitializeAMDGPUAsmPrinter() void; | |
| 232 | extern fn LLVMInitializeARMAsmPrinter() void; | |
| 233 | extern fn LLVMInitializeAVRAsmPrinter() void; | |
| 234 | extern fn LLVMInitializeBPFAsmPrinter() void; | |
| 235 | extern fn LLVMInitializeHexagonAsmPrinter() void; | |
| 236 | extern fn LLVMInitializeLanaiAsmPrinter() void; | |
| 237 | extern fn LLVMInitializeMipsAsmPrinter() void; | |
| 238 | extern fn LLVMInitializeMSP430AsmPrinter() void; | |
| 239 | extern fn LLVMInitializeNVPTXAsmPrinter() void; | |
| 240 | extern fn LLVMInitializePowerPCAsmPrinter() void; | |
| 241 | extern fn LLVMInitializeRISCVAsmPrinter() void; | |
| 242 | extern fn LLVMInitializeSparcAsmPrinter() void; | |
| 243 | extern fn LLVMInitializeSystemZAsmPrinter() void; | |
| 244 | extern fn LLVMInitializeWebAssemblyAsmPrinter() void; | |
| 245 | extern fn LLVMInitializeX86AsmPrinter() void; | |
| 246 | extern fn LLVMInitializeXCoreAsmPrinter() void; | |
| 247 | extern fn LLVMInitializeAArch64AsmParser() void; | |
| 248 | extern fn LLVMInitializeAMDGPUAsmParser() void; | |
| 249 | extern fn LLVMInitializeARMAsmParser() void; | |
| 250 | extern fn LLVMInitializeAVRAsmParser() void; | |
| 251 | extern fn LLVMInitializeBPFAsmParser() void; | |
| 252 | extern fn LLVMInitializeHexagonAsmParser() void; | |
| 253 | extern fn LLVMInitializeLanaiAsmParser() void; | |
| 254 | extern fn LLVMInitializeMipsAsmParser() void; | |
| 255 | extern fn LLVMInitializeMSP430AsmParser() void; | |
| 256 | extern fn LLVMInitializePowerPCAsmParser() void; | |
| 257 | extern fn LLVMInitializeRISCVAsmParser() void; | |
| 258 | extern fn LLVMInitializeSparcAsmParser() void; | |
| 259 | extern fn LLVMInitializeSystemZAsmParser() void; | |
| 260 | extern fn LLVMInitializeWebAssemblyAsmParser() void; | |
| 261 | extern fn LLVMInitializeX86AsmParser() void; | |
| 262 | ||
| 263 | pub const initializeAllTargetInfos = LLVMInitializeAllTargetInfos; | |
| 264 | fn LLVMInitializeAllTargetInfos() callconv(.C) void { | |
| 265 | LLVMInitializeAArch64TargetInfo(); | |
| 266 | LLVMInitializeAMDGPUTargetInfo(); | |
| 267 | LLVMInitializeARMTargetInfo(); | |
| 268 | LLVMInitializeAVRTargetInfo(); | |
| 269 | LLVMInitializeBPFTargetInfo(); | |
| 270 | LLVMInitializeHexagonTargetInfo(); | |
| 271 | LLVMInitializeLanaiTargetInfo(); | |
| 272 | LLVMInitializeMipsTargetInfo(); | |
| 273 | LLVMInitializeMSP430TargetInfo(); | |
| 274 | LLVMInitializeNVPTXTargetInfo(); | |
| 275 | LLVMInitializePowerPCTargetInfo(); | |
| 276 | LLVMInitializeRISCVTargetInfo(); | |
| 277 | LLVMInitializeSparcTargetInfo(); | |
| 278 | LLVMInitializeSystemZTargetInfo(); | |
| 279 | LLVMInitializeWebAssemblyTargetInfo(); | |
| 280 | LLVMInitializeX86TargetInfo(); | |
| 281 | LLVMInitializeXCoreTargetInfo(); | |
| 282 | } | |
| 283 | pub const initializeAllTargets = LLVMInitializeAllTargets; | |
| 284 | fn LLVMInitializeAllTargets() callconv(.C) void { | |
| 285 | LLVMInitializeAArch64Target(); | |
| 286 | LLVMInitializeAMDGPUTarget(); | |
| 287 | LLVMInitializeARMTarget(); | |
| 288 | LLVMInitializeAVRTarget(); | |
| 289 | LLVMInitializeBPFTarget(); | |
| 290 | LLVMInitializeHexagonTarget(); | |
| 291 | LLVMInitializeLanaiTarget(); | |
| 292 | LLVMInitializeMipsTarget(); | |
| 293 | LLVMInitializeMSP430Target(); | |
| 294 | LLVMInitializeNVPTXTarget(); | |
| 295 | LLVMInitializePowerPCTarget(); | |
| 296 | LLVMInitializeRISCVTarget(); | |
| 297 | LLVMInitializeSparcTarget(); | |
| 298 | LLVMInitializeSystemZTarget(); | |
| 299 | LLVMInitializeWebAssemblyTarget(); | |
| 300 | LLVMInitializeX86Target(); | |
| 301 | LLVMInitializeXCoreTarget(); | |
| 302 | } | |
| 303 | pub const initializeAllTargetMCs = LLVMInitializeAllTargetMCs; | |
| 304 | fn LLVMInitializeAllTargetMCs() callconv(.C) void { | |
| 305 | LLVMInitializeAArch64TargetMC(); | |
| 306 | LLVMInitializeAMDGPUTargetMC(); | |
| 307 | LLVMInitializeARMTargetMC(); | |
| 308 | LLVMInitializeAVRTargetMC(); | |
| 309 | LLVMInitializeBPFTargetMC(); | |
| 310 | LLVMInitializeHexagonTargetMC(); | |
| 311 | LLVMInitializeLanaiTargetMC(); | |
| 312 | LLVMInitializeMipsTargetMC(); | |
| 313 | LLVMInitializeMSP430TargetMC(); | |
| 314 | LLVMInitializeNVPTXTargetMC(); | |
| 315 | LLVMInitializePowerPCTargetMC(); | |
| 316 | LLVMInitializeRISCVTargetMC(); | |
| 317 | LLVMInitializeSparcTargetMC(); | |
| 318 | LLVMInitializeSystemZTargetMC(); | |
| 319 | LLVMInitializeWebAssemblyTargetMC(); | |
| 320 | LLVMInitializeX86TargetMC(); | |
| 321 | LLVMInitializeXCoreTargetMC(); | |
| 322 | } | |
| 323 | pub const initializeAllAsmPrinters = LLVMInitializeAllAsmPrinters; | |
| 324 | fn LLVMInitializeAllAsmPrinters() callconv(.C) void { | |
| 325 | LLVMInitializeAArch64AsmPrinter(); | |
| 326 | LLVMInitializeAMDGPUAsmPrinter(); | |
| 327 | LLVMInitializeARMAsmPrinter(); | |
| 328 | LLVMInitializeAVRAsmPrinter(); | |
| 329 | LLVMInitializeBPFAsmPrinter(); | |
| 330 | LLVMInitializeHexagonAsmPrinter(); | |
| 331 | LLVMInitializeLanaiAsmPrinter(); | |
| 332 | LLVMInitializeMipsAsmPrinter(); | |
| 333 | LLVMInitializeMSP430AsmPrinter(); | |
| 334 | LLVMInitializeNVPTXAsmPrinter(); | |
| 335 | LLVMInitializePowerPCAsmPrinter(); | |
| 336 | LLVMInitializeRISCVAsmPrinter(); | |
| 337 | LLVMInitializeSparcAsmPrinter(); | |
| 338 | LLVMInitializeSystemZAsmPrinter(); | |
| 339 | LLVMInitializeWebAssemblyAsmPrinter(); | |
| 340 | LLVMInitializeX86AsmPrinter(); | |
| 341 | LLVMInitializeXCoreAsmPrinter(); | |
| 342 | } | |
| 343 | pub const initializeAllAsmParsers = LLVMInitializeAllAsmParsers; | |
| 344 | fn LLVMInitializeAllAsmParsers() callconv(.C) void { | |
| 345 | LLVMInitializeAArch64AsmParser(); | |
| 346 | LLVMInitializeAMDGPUAsmParser(); | |
| 347 | LLVMInitializeARMAsmParser(); | |
| 348 | LLVMInitializeAVRAsmParser(); | |
| 349 | LLVMInitializeBPFAsmParser(); | |
| 350 | LLVMInitializeHexagonAsmParser(); | |
| 351 | LLVMInitializeLanaiAsmParser(); | |
| 352 | LLVMInitializeMipsAsmParser(); | |
| 353 | LLVMInitializeMSP430AsmParser(); | |
| 354 | LLVMInitializePowerPCAsmParser(); | |
| 355 | LLVMInitializeRISCVAsmParser(); | |
| 356 | LLVMInitializeSparcAsmParser(); | |
| 357 | LLVMInitializeSystemZAsmParser(); | |
| 358 | LLVMInitializeWebAssemblyAsmParser(); | |
| 359 | LLVMInitializeX86AsmParser(); | |
| 360 | } | |
| 361 | ||
| 4 | 362 | extern fn ZigLLDLinkCOFF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int; |
| 5 | 363 | extern fn ZigLLDLinkELF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int; |
| 6 | 364 | extern fn ZigLLDLinkMachO(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int; |