authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-06-12 20:46:36-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-06-12 20:46:36-04:00
logdcdb4422b801f2d184107fdd7b9493f7840a0244
treeca7a37c544382c10e45fbad68ea7701a05d0543c
parent5e3c0b7af7cd866f5464c244b9775e488b93ae48
parent43d01ff69f6c6c46bef81dd4de2c78fb0a942b65
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #24124 from mlugg/better-backend-pipeline-2

compiler: threaded codegen (and more goodies)

74 files changed, 8061 insertions(+), 7609 deletions(-)

CMakeLists.txt+2-1
...@@ -535,7 +535,6 @@ set(ZIG_STAGE2_SOURCES...@@ -535,7 +535,6 @@ set(ZIG_STAGE2_SOURCES
535 src/Sema.zig535 src/Sema.zig
536 src/Sema/bitcast.zig536 src/Sema/bitcast.zig
537 src/Sema/comptime_ptr_access.zig537 src/Sema/comptime_ptr_access.zig
538 src/ThreadSafeQueue.zig
539 src/Type.zig538 src/Type.zig
540 src/Value.zig539 src/Value.zig
541 src/Zcu.zig540 src/Zcu.zig
...@@ -624,6 +623,7 @@ set(ZIG_STAGE2_SOURCES...@@ -624,6 +623,7 @@ set(ZIG_STAGE2_SOURCES
624 src/link/Elf/synthetic_sections.zig623 src/link/Elf/synthetic_sections.zig
625 src/link/Goff.zig624 src/link/Goff.zig
626 src/link/LdScript.zig625 src/link/LdScript.zig
626 src/link/Lld.zig
627 src/link/MachO.zig627 src/link/MachO.zig
628 src/link/MachO/Archive.zig628 src/link/MachO/Archive.zig
629 src/link/MachO/Atom.zig629 src/link/MachO/Atom.zig
...@@ -652,6 +652,7 @@ set(ZIG_STAGE2_SOURCES...@@ -652,6 +652,7 @@ set(ZIG_STAGE2_SOURCES
652 src/link/MachO/uuid.zig652 src/link/MachO/uuid.zig
653 src/link/Plan9.zig653 src/link/Plan9.zig
654 src/link/Plan9/aout.zig654 src/link/Plan9/aout.zig
655 src/link/Queue.zig
655 src/link/SpirV.zig656 src/link/SpirV.zig
656 src/link/SpirV/BinaryModule.zig657 src/link/SpirV/BinaryModule.zig
657 src/link/SpirV/deduplicate.zig658 src/link/SpirV/deduplicate.zig
lib/std/Build/Step/Compile.zig+25-41
...@@ -1834,47 +1834,16 @@ fn make(step: *Step, options: Step.MakeOptions) !void {...@@ -1834,47 +1834,16 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
1834 lp.path = b.fmt("{}", .{output_dir});1834 lp.path = b.fmt("{}", .{output_dir});
1835 }1835 }
18361836
1837 // -femit-bin[=path] (default) Output machine code1837 // zig fmt: off
1838 if (compile.generated_bin) |bin| {1838 if (compile.generated_bin) |lp| lp.path = compile.outputPath(output_dir, .bin);
1839 bin.path = output_dir.joinString(b.allocator, compile.out_filename) catch @panic("OOM");1839 if (compile.generated_pdb) |lp| lp.path = compile.outputPath(output_dir, .pdb);
1840 }1840 if (compile.generated_implib) |lp| lp.path = compile.outputPath(output_dir, .implib);
18411841 if (compile.generated_h) |lp| lp.path = compile.outputPath(output_dir, .h);
1842 const sep = std.fs.path.sep_str;1842 if (compile.generated_docs) |lp| lp.path = compile.outputPath(output_dir, .docs);
18431843 if (compile.generated_asm) |lp| lp.path = compile.outputPath(output_dir, .@"asm");
1844 // output PDB if someone requested it1844 if (compile.generated_llvm_ir) |lp| lp.path = compile.outputPath(output_dir, .llvm_ir);
1845 if (compile.generated_pdb) |pdb| {1845 if (compile.generated_llvm_bc) |lp| lp.path = compile.outputPath(output_dir, .llvm_bc);
1846 pdb.path = b.fmt("{}" ++ sep ++ "{s}.pdb", .{ output_dir, compile.name });1846 // zig fmt: on
1847 }
1848
1849 // -femit-implib[=path] (default) Produce an import .lib when building a Windows DLL
1850 if (compile.generated_implib) |implib| {
1851 implib.path = b.fmt("{}" ++ sep ++ "{s}.lib", .{ output_dir, compile.name });
1852 }
1853
1854 // -femit-h[=path] Generate a C header file (.h)
1855 if (compile.generated_h) |lp| {
1856 lp.path = b.fmt("{}" ++ sep ++ "{s}.h", .{ output_dir, compile.name });
1857 }
1858
1859 // -femit-docs[=path] Create a docs/ dir with html documentation
1860 if (compile.generated_docs) |generated_docs| {
1861 generated_docs.path = output_dir.joinString(b.allocator, "docs") catch @panic("OOM");
1862 }
1863
1864 // -femit-asm[=path] Output .s (assembly code)
1865 if (compile.generated_asm) |lp| {
1866 lp.path = b.fmt("{}" ++ sep ++ "{s}.s", .{ output_dir, compile.name });
1867 }
1868
1869 // -femit-llvm-ir[=path] Produce a .ll file with optimized LLVM IR (requires LLVM extensions)
1870 if (compile.generated_llvm_ir) |lp| {
1871 lp.path = b.fmt("{}" ++ sep ++ "{s}.ll", .{ output_dir, compile.name });
1872 }
1873
1874 // -femit-llvm-bc[=path] Produce an optimized LLVM module as a .bc file (requires LLVM extensions)
1875 if (compile.generated_llvm_bc) |lp| {
1876 lp.path = b.fmt("{}" ++ sep ++ "{s}.bc", .{ output_dir, compile.name });
1877 }
1878 }1847 }
18791848
1880 if (compile.kind == .lib and compile.linkage != null and compile.linkage.? == .dynamic and1849 if (compile.kind == .lib and compile.linkage != null and compile.linkage.? == .dynamic and
...@@ -1888,6 +1857,21 @@ fn make(step: *Step, options: Step.MakeOptions) !void {...@@ -1888,6 +1857,21 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
1888 );1857 );
1889 }1858 }
1890}1859}
1860fn outputPath(c: *Compile, out_dir: std.Build.Cache.Path, ea: std.zig.EmitArtifact) []const u8 {
1861 const arena = c.step.owner.graph.arena;
1862 const name = ea.cacheName(arena, .{
1863 .root_name = c.name,
1864 .target = c.root_module.resolved_target.?.result,
1865 .output_mode = switch (c.kind) {
1866 .lib => .Lib,
1867 .obj, .test_obj => .Obj,
1868 .exe, .@"test" => .Exe,
1869 },
1870 .link_mode = c.linkage,
1871 .version = c.version,
1872 }) catch @panic("OOM");
1873 return out_dir.joinString(arena, name) catch @panic("OOM");
1874}
18911875
1892pub fn rebuildInFuzzMode(c: *Compile, progress_node: std.Progress.Node) !Path {1876pub fn rebuildInFuzzMode(c: *Compile, progress_node: std.Progress.Node) !Path {
1893 const gpa = c.step.owner.allocator;1877 const gpa = c.step.owner.allocator;
lib/std/Progress.zig+22
...@@ -234,6 +234,28 @@ pub const Node = struct {...@@ -234,6 +234,28 @@ pub const Node = struct {
234 _ = @atomicRmw(u32, &storage.completed_count, .Add, 1, .monotonic);234 _ = @atomicRmw(u32, &storage.completed_count, .Add, 1, .monotonic);
235 }235 }
236236
237 /// Thread-safe. Bytes after '0' in `new_name` are ignored.
238 pub fn setName(n: Node, new_name: []const u8) void {
239 const index = n.index.unwrap() orelse return;
240 const storage = storageByIndex(index);
241
242 const name_len = @min(max_name_len, std.mem.indexOfScalar(u8, new_name, 0) orelse new_name.len);
243
244 copyAtomicStore(storage.name[0..name_len], new_name[0..name_len]);
245 if (name_len < storage.name.len)
246 @atomicStore(u8, &storage.name[name_len], 0, .monotonic);
247 }
248
249 /// Gets the name of this `Node`.
250 /// A pointer to this array can later be passed to `setName` to restore the name.
251 pub fn getName(n: Node) [max_name_len]u8 {
252 var dest: [max_name_len]u8 align(@alignOf(usize)) = undefined;
253 if (n.index.unwrap()) |index| {
254 copyAtomicLoad(&dest, &storageByIndex(index).name);
255 }
256 return dest;
257 }
258
237 /// Thread-safe.259 /// Thread-safe.
238 pub fn setCompletedItems(n: Node, completed_items: usize) void {260 pub fn setCompletedItems(n: Node, completed_items: usize) void {
239 const index = n.index.unwrap() orelse return;261 const index = n.index.unwrap() orelse return;
lib/std/heap/debug_allocator.zig+2-2
...@@ -212,8 +212,8 @@ pub fn DebugAllocator(comptime config: Config) type {...@@ -212,8 +212,8 @@ pub fn DebugAllocator(comptime config: Config) type {
212 DummyMutex{};212 DummyMutex{};
213213
214 const DummyMutex = struct {214 const DummyMutex = struct {
215 inline fn lock(_: *DummyMutex) void {}215 inline fn lock(_: DummyMutex) void {}
216 inline fn unlock(_: *DummyMutex) void {}216 inline fn unlock(_: DummyMutex) void {}
217 };217 };
218218
219 const stack_n = config.stack_trace_frames;219 const stack_n = config.stack_trace_frames;
lib/std/multi_array_list.zig+16
...@@ -135,6 +135,22 @@ pub fn MultiArrayList(comptime T: type) type {...@@ -135,6 +135,22 @@ pub fn MultiArrayList(comptime T: type) type {
135 self.* = undefined;135 self.* = undefined;
136 }136 }
137137
138 /// Returns a `Slice` representing a range of elements in `s`, analagous to `arr[off..len]`.
139 /// It is illegal to call `deinit` or `toMultiArrayList` on the returned `Slice`.
140 /// Asserts that `off + len <= s.len`.
141 pub fn subslice(s: Slice, off: usize, len: usize) Slice {
142 assert(off + len <= s.len);
143 var ptrs: [fields.len][*]u8 = undefined;
144 inline for (s.ptrs, &ptrs, fields) |in, *out, field| {
145 out.* = in + (off * @sizeOf(field.type));
146 }
147 return .{
148 .ptrs = ptrs,
149 .len = len,
150 .capacity = len,
151 };
152 }
153
138 /// This function is used in the debugger pretty formatters in tools/ to fetch the154 /// This function is used in the debugger pretty formatters in tools/ to fetch the
139 /// child field order and entry type to facilitate fancy debug printing for this type.155 /// child field order and entry type to facilitate fancy debug printing for this type.
140 fn dbHelper(self: *Slice, child: *Elem, field: *Field, entry: *Entry) void {156 fn dbHelper(self: *Slice, child: *Elem, field: *Field, entry: *Entry) void {
lib/std/zig.zig+29
...@@ -884,6 +884,35 @@ pub const SimpleComptimeReason = enum(u32) {...@@ -884,6 +884,35 @@ pub const SimpleComptimeReason = enum(u32) {
884 }884 }
885};885};
886886
887/// Every kind of artifact which the compiler can emit.
888pub const EmitArtifact = enum {
889 bin,
890 @"asm",
891 implib,
892 llvm_ir,
893 llvm_bc,
894 docs,
895 pdb,
896 h,
897
898 /// If using `Server` to communicate with the compiler, it will place requested artifacts in
899 /// paths under the output directory, where those paths are named according to this function.
900 /// Returned string is allocated with `gpa` and owned by the caller.
901 pub fn cacheName(ea: EmitArtifact, gpa: Allocator, opts: BinNameOptions) Allocator.Error![]const u8 {
902 const suffix: []const u8 = switch (ea) {
903 .bin => return binNameAlloc(gpa, opts),
904 .@"asm" => ".s",
905 .implib => ".lib",
906 .llvm_ir => ".ll",
907 .llvm_bc => ".bc",
908 .docs => "-docs",
909 .pdb => ".pdb",
910 .h => ".h",
911 };
912 return std.fmt.allocPrint(gpa, "{s}{s}", .{ opts.root_name, suffix });
913 }
914};
915
887test {916test {
888 _ = Ast;917 _ = Ast;
889 _ = AstRlAnnotate;918 _ = AstRlAnnotate;
lib/std/zig/Zir.zig+9
...@@ -4861,6 +4861,15 @@ pub fn getParamBody(zir: Zir, fn_inst: Inst.Index) []const Zir.Inst.Index {...@@ -4861,6 +4861,15 @@ pub fn getParamBody(zir: Zir, fn_inst: Inst.Index) []const Zir.Inst.Index {
4861 }4861 }
4862}4862}
48634863
4864pub fn getParamName(zir: Zir, param_inst: Inst.Index) ?NullTerminatedString {
4865 const inst = zir.instructions.get(@intFromEnum(param_inst));
4866 return switch (inst.tag) {
4867 .param, .param_comptime => zir.extraData(Inst.Param, inst.data.pl_tok.payload_index).data.name,
4868 .param_anytype, .param_anytype_comptime => inst.data.str_tok.start,
4869 else => null,
4870 };
4871}
4872
4864pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {4873pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {
4865 const tags = zir.instructions.items(.tag);4874 const tags = zir.instructions.items(.tag);
4866 const datas = zir.instructions.items(.data);4875 const datas = zir.instructions.items(.data);
src/Air.zig+1-3
...@@ -1153,9 +1153,7 @@ pub const Inst = struct {...@@ -1153,9 +1153,7 @@ pub const Inst = struct {
1153 ty: Type,1153 ty: Type,
1154 arg: struct {1154 arg: struct {
1155 ty: Ref,1155 ty: Ref,
1156 /// Index into `extra` of a null-terminated string representing the parameter name.1156 zir_param_index: u32,
1157 /// This is `.none` if debug info is stripped.
1158 name: NullTerminatedString,
1159 },1157 },
1160 ty_op: struct {1158 ty_op: struct {
1161 ty: Ref,1159 ty: Ref,
src/Air/print.zig+1-4
...@@ -363,10 +363,7 @@ const Writer = struct {...@@ -363,10 +363,7 @@ const Writer = struct {
363 fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {363 fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
364 const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg;364 const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg;
365 try w.writeType(s, arg.ty.toType());365 try w.writeType(s, arg.ty.toType());
366 switch (arg.name) {366 try s.print(", {d}", .{arg.zir_param_index});
367 .none => {},
368 _ => try s.print(", \"{}\"", .{std.zig.fmtEscapes(arg.name.toSlice(w.air))}),
369 }
370 }367 }
371368
372 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {369 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
src/Compilation.zig+611-497
...@@ -43,7 +43,6 @@ const Air = @import("Air.zig");...@@ -43,7 +43,6 @@ const Air = @import("Air.zig");
43const Builtin = @import("Builtin.zig");43const Builtin = @import("Builtin.zig");
44const LlvmObject = @import("codegen/llvm.zig").Object;44const LlvmObject = @import("codegen/llvm.zig").Object;
45const dev = @import("dev.zig");45const dev = @import("dev.zig");
46const ThreadSafeQueue = @import("ThreadSafeQueue.zig").ThreadSafeQueue;
4746
48pub const Config = @import("Compilation/Config.zig");47pub const Config = @import("Compilation/Config.zig");
4948
...@@ -56,8 +55,7 @@ gpa: Allocator,...@@ -56,8 +55,7 @@ gpa: Allocator,
56arena: Allocator,55arena: Allocator,
57/// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`.56/// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`.
58zcu: ?*Zcu,57zcu: ?*Zcu,
59/// Contains different state depending on whether the Compilation uses58/// Contains different state depending on the `CacheMode` used by this `Compilation`.
60/// incremental or whole cache mode.
61cache_use: CacheUse,59cache_use: CacheUse,
62/// All compilations have a root module because this is where some important60/// All compilations have a root module because this is where some important
63/// settings are stored, such as target and optimization mode. This module61/// settings are stored, such as target and optimization mode. This module
...@@ -68,17 +66,13 @@ root_mod: *Package.Module,...@@ -68,17 +66,13 @@ root_mod: *Package.Module,
68config: Config,66config: Config,
6967
70/// The main output file.68/// The main output file.
71/// In whole cache mode, this is null except for during the body of the update69/// In `CacheMode.whole`, this is null except for during the body of `update`.
72/// function. In incremental cache mode, this is a long-lived object.70/// In `CacheMode.none` and `CacheMode.incremental`, this is long-lived.
73/// In both cases, this is `null` when `-fno-emit-bin` is used.71/// Regardless of cache mode, this is `null` when `-fno-emit-bin` is used.
74bin_file: ?*link.File,72bin_file: ?*link.File,
7573
76/// The root path for the dynamic linker and system libraries (as well as frameworks on Darwin)74/// The root path for the dynamic linker and system libraries (as well as frameworks on Darwin)
77sysroot: ?[]const u8,75sysroot: ?[]const u8,
78/// This is `null` when not building a Windows DLL, or when `-fno-emit-implib` is used.
79implib_emit: ?Cache.Path,
80/// This is non-null when `-femit-docs` is provided.
81docs_emit: ?Cache.Path,
82root_name: [:0]const u8,76root_name: [:0]const u8,
83compiler_rt_strat: RtStrat,77compiler_rt_strat: RtStrat,
84ubsan_rt_strat: RtStrat,78ubsan_rt_strat: RtStrat,
...@@ -113,17 +107,7 @@ win32_resource_table: if (dev.env.supports(.win32_resource)) std.AutoArrayHashMa...@@ -113,17 +107,7 @@ win32_resource_table: if (dev.env.supports(.win32_resource)) std.AutoArrayHashMa
113} = .{},107} = .{},
114108
115link_diags: link.Diags,109link_diags: link.Diags,
116link_task_queue: ThreadSafeQueue(link.Task) = .empty,110link_task_queue: link.Queue = .empty,
117/// Ensure only 1 simultaneous call to `flushTaskQueue`.
118link_task_queue_safety: std.debug.SafetyLock = .{},
119/// If any tasks are queued up that depend on prelink being finished, they are moved
120/// here until prelink finishes.
121link_task_queue_postponed: std.ArrayListUnmanaged(link.Task) = .empty,
122/// Initialized with how many link input tasks are expected. After this reaches zero
123/// the linker will begin the prelink phase.
124/// Initialized in the Compilation main thread before the pipeline; modified only in
125/// the linker task thread.
126remaining_prelink_tasks: u32,
127111
128/// Set of work that can be represented by only flags to determine whether the112/// Set of work that can be represented by only flags to determine whether the
129/// work is queued or not.113/// work is queued or not.
...@@ -270,12 +254,8 @@ mutex: if (builtin.single_threaded) struct {...@@ -270,12 +254,8 @@ mutex: if (builtin.single_threaded) struct {
270test_filters: []const []const u8,254test_filters: []const []const u8,
271test_name_prefix: ?[]const u8,255test_name_prefix: ?[]const u8,
272256
273emit_asm: ?EmitLoc,
274emit_llvm_ir: ?EmitLoc,
275emit_llvm_bc: ?EmitLoc,
276
277link_task_wait_group: WaitGroup = .{},257link_task_wait_group: WaitGroup = .{},
278work_queue_progress_node: std.Progress.Node = .none,258link_prog_node: std.Progress.Node = std.Progress.Node.none,
279259
280llvm_opt_bisect_limit: c_int,260llvm_opt_bisect_limit: c_int,
281261
...@@ -285,6 +265,31 @@ file_system_inputs: ?*std.ArrayListUnmanaged(u8),...@@ -285,6 +265,31 @@ file_system_inputs: ?*std.ArrayListUnmanaged(u8),
285/// This digest will be known after update() is called.265/// This digest will be known after update() is called.
286digest: ?[Cache.bin_digest_len]u8 = null,266digest: ?[Cache.bin_digest_len]u8 = null,
287267
268/// Non-`null` iff we are emitting a binary.
269/// Does not change for the lifetime of this `Compilation`.
270/// Cwd-relative if `cache_use == .none`. Otherwise, relative to our subdirectory in the cache.
271emit_bin: ?[]const u8,
272/// Non-`null` iff we are emitting assembly.
273/// Does not change for the lifetime of this `Compilation`.
274/// Cwd-relative if `cache_use == .none`. Otherwise, relative to our subdirectory in the cache.
275emit_asm: ?[]const u8,
276/// Non-`null` iff we are emitting an implib.
277/// Does not change for the lifetime of this `Compilation`.
278/// Cwd-relative if `cache_use == .none`. Otherwise, relative to our subdirectory in the cache.
279emit_implib: ?[]const u8,
280/// Non-`null` iff we are emitting LLVM IR.
281/// Does not change for the lifetime of this `Compilation`.
282/// Cwd-relative if `cache_use == .none`. Otherwise, relative to our subdirectory in the cache.
283emit_llvm_ir: ?[]const u8,
284/// Non-`null` iff we are emitting LLVM bitcode.
285/// Does not change for the lifetime of this `Compilation`.
286/// Cwd-relative if `cache_use == .none`. Otherwise, relative to our subdirectory in the cache.
287emit_llvm_bc: ?[]const u8,
288/// Non-`null` iff we are emitting documentation.
289/// Does not change for the lifetime of this `Compilation`.
290/// Cwd-relative if `cache_use == .none`. Otherwise, relative to our subdirectory in the cache.
291emit_docs: ?[]const u8,
292
288const QueuedJobs = struct {293const QueuedJobs = struct {
289 compiler_rt_lib: bool = false,294 compiler_rt_lib: bool = false,
290 compiler_rt_obj: bool = false,295 compiler_rt_obj: bool = false,
...@@ -785,13 +790,6 @@ pub const CrtFile = struct {...@@ -785,13 +790,6 @@ pub const CrtFile = struct {
785 lock: Cache.Lock,790 lock: Cache.Lock,
786 full_object_path: Cache.Path,791 full_object_path: Cache.Path,
787792
788 pub fn isObject(cf: CrtFile) bool {
789 return switch (classifyFileExt(cf.full_object_path.sub_path)) {
790 .object => true,
791 else => false,
792 };
793 }
794
795 pub fn deinit(self: *CrtFile, gpa: Allocator) void {793 pub fn deinit(self: *CrtFile, gpa: Allocator) void {
796 self.lock.release();794 self.lock.release();
797 gpa.free(self.full_object_path.sub_path);795 gpa.free(self.full_object_path.sub_path);
...@@ -846,19 +844,34 @@ pub const RcIncludes = enum {...@@ -846,19 +844,34 @@ pub const RcIncludes = enum {
846};844};
847845
848const Job = union(enum) {846const Job = union(enum) {
849 /// Corresponds to the task in `link.Task`.847 /// Given the generated AIR for a function, put it onto the code generation queue.
850 /// Only needed for backends that haven't yet been updated to not race against Sema.848 /// This `Job` exists (instead of the `link.ZcuTask` being directly queued) to ensure that
851 codegen_nav: InternPool.Nav.Index,849 /// all types are resolved before the linker task is queued.
852 /// Corresponds to the task in `link.Task`.850 /// If the backend does not support `Zcu.Feature.separate_thread`, codegen and linking happen immediately.
853 /// Only needed for backends that haven't yet been updated to not race against Sema.851 /// Before queueing this `Job`, increase the estimated total item count for both
854 codegen_func: link.Task.CodegenFunc,852 /// `comp.zcu.?.codegen_prog_node` and `comp.link_prog_node`.
855 /// Corresponds to the task in `link.Task`.853 codegen_func: struct {
856 /// Only needed for backends that haven't yet been updated to not race against Sema.854 func: InternPool.Index,
857 codegen_type: InternPool.Index,855 /// The AIR emitted from analyzing `func`; owned by this `Job` in `gpa`.
856 air: Air,
857 },
858 /// Queue a `link.ZcuTask` to emit this non-function `Nav` into the output binary.
859 /// This `Job` exists (instead of the `link.ZcuTask` being directly queued) to ensure that
860 /// all types are resolved before the linker task is queued.
861 /// If the backend does not support `Zcu.Feature.separate_thread`, the task is run immediately.
862 /// Before queueing this `Job`, increase the estimated total item count for `comp.link_prog_node`.
863 link_nav: InternPool.Nav.Index,
864 /// Queue a `link.ZcuTask` to emit debug information for this container type.
865 /// This `Job` exists (instead of the `link.ZcuTask` being directly queued) to ensure that
866 /// all types are resolved before the linker task is queued.
867 /// If the backend does not support `Zcu.Feature.separate_thread`, the task is run immediately.
868 /// Before queueing this `Job`, increase the estimated total item count for `comp.link_prog_node`.
869 link_type: InternPool.Index,
870 /// Before queueing this `Job`, increase the estimated total item count for `comp.link_prog_node`.
858 update_line_number: InternPool.TrackedInst.Index,871 update_line_number: InternPool.TrackedInst.Index,
859 /// The `AnalUnit`, which is *not* a `func`, must be semantically analyzed.872 /// The `AnalUnit`, which is *not* a `func`, must be semantically analyzed.
860 /// This may be its first time being analyzed, or it may be outdated.873 /// This may be its first time being analyzed, or it may be outdated.
861 /// If the unit is a function, a `codegen_func` job will then be queued.874 /// If the unit is a test function, an `analyze_func` job will then be queued.
862 analyze_comptime_unit: InternPool.AnalUnit,875 analyze_comptime_unit: InternPool.AnalUnit,
863 /// This function must be semantically analyzed.876 /// This function must be semantically analyzed.
864 /// This may be its first time being analyzed, or it may be outdated.877 /// This may be its first time being analyzed, or it may be outdated.
...@@ -1322,14 +1335,6 @@ pub const MiscError = struct {...@@ -1322,14 +1335,6 @@ pub const MiscError = struct {
1322 }1335 }
1323};1336};
13241337
1325pub const EmitLoc = struct {
1326 /// If this is `null` it means the file will be output to the cache directory.
1327 /// When provided, both the open file handle and the path name must outlive the `Compilation`.
1328 directory: ?Cache.Directory,
1329 /// This may not have sub-directories in it.
1330 basename: []const u8,
1331};
1332
1333pub const cache_helpers = struct {1338pub const cache_helpers = struct {
1334 pub fn addModule(hh: *Cache.HashHelper, mod: *const Package.Module) void {1339 pub fn addModule(hh: *Cache.HashHelper, mod: *const Package.Module) void {
1335 addResolvedTarget(hh, mod.resolved_target);1340 addResolvedTarget(hh, mod.resolved_target);
...@@ -1369,15 +1374,6 @@ pub const cache_helpers = struct {...@@ -1369,15 +1374,6 @@ pub const cache_helpers = struct {
1369 hh.add(resolved_target.is_explicit_dynamic_linker);1374 hh.add(resolved_target.is_explicit_dynamic_linker);
1370 }1375 }
13711376
1372 pub fn addEmitLoc(hh: *Cache.HashHelper, emit_loc: EmitLoc) void {
1373 hh.addBytes(emit_loc.basename);
1374 }
1375
1376 pub fn addOptionalEmitLoc(hh: *Cache.HashHelper, optional_emit_loc: ?EmitLoc) void {
1377 hh.add(optional_emit_loc != null);
1378 addEmitLoc(hh, optional_emit_loc orelse return);
1379 }
1380
1381 pub fn addOptionalDebugFormat(hh: *Cache.HashHelper, x: ?Config.DebugFormat) void {1377 pub fn addOptionalDebugFormat(hh: *Cache.HashHelper, x: ?Config.DebugFormat) void {
1382 hh.add(x != null);1378 hh.add(x != null);
1383 addDebugFormat(hh, x orelse return);1379 addDebugFormat(hh, x orelse return);
...@@ -1424,7 +1420,38 @@ pub const ClangPreprocessorMode = enum {...@@ -1424,7 +1420,38 @@ pub const ClangPreprocessorMode = enum {
1424pub const Framework = link.File.MachO.Framework;1420pub const Framework = link.File.MachO.Framework;
1425pub const SystemLib = link.SystemLib;1421pub const SystemLib = link.SystemLib;
14261422
1427pub const CacheMode = enum { incremental, whole };1423pub const CacheMode = enum {
1424 /// The results of this compilation are not cached. The compilation is always performed, and the
1425 /// results are emitted directly to their output locations. Temporary files will be placed in a
1426 /// temporary directory in the cache, but deleted after the compilation is done.
1427 ///
1428 /// This mode is typically used for direct CLI invocations like `zig build-exe`, because such
1429 /// processes are typically low-level usages which would not make efficient use of the cache.
1430 none,
1431 /// The compilation is cached based only on the options given when creating the `Compilation`.
1432 /// In particular, Zig source file contents are not included in the cache manifest. This mode
1433 /// allows incremental compilation, because the old cached compilation state can be restored
1434 /// and the old binary patched up with the changes. All files, including temporary files, are
1435 /// stored in the cache directory like '<cache>/o/<hash>/'. Temporary files are not deleted.
1436 ///
1437 /// At the time of writing, incremental compilation is only supported with the `-fincremental`
1438 /// command line flag, so this mode is rarely used. However, it is required in order to use
1439 /// incremental compilation.
1440 incremental,
1441 /// The compilation is cached based on the `Compilation` options and every input, including Zig
1442 /// source files, linker inputs, and `@embedFile` targets. If any of them change, we will see a
1443 /// cache miss, and the entire compilation will be re-run. On a cache miss, we initially write
1444 /// all output files to a directory under '<cache>/tmp/', because we don't know the final
1445 /// manifest digest until the update is almost done. Once we can compute the final digest, this
1446 /// directory is moved to '<cache>/o/<hash>/'. Temporary files are not deleted.
1447 ///
1448 /// At the time of writing, this is the most commonly used cache mode: it is used by the build
1449 /// system (and any other parent using `--listen`) unless incremental compilation is enabled.
1450 /// Once incremental compilation is more mature, it will be replaced by `incremental` in many
1451 /// cases, but still has use cases, such as for release binaries, particularly globally cached
1452 /// artifacts like compiler_rt.
1453 whole,
1454};
14281455
1429pub const ParentWholeCache = struct {1456pub const ParentWholeCache = struct {
1430 manifest: *Cache.Manifest,1457 manifest: *Cache.Manifest,
...@@ -1433,22 +1460,33 @@ pub const ParentWholeCache = struct {...@@ -1433,22 +1460,33 @@ pub const ParentWholeCache = struct {
1433};1460};
14341461
1435const CacheUse = union(CacheMode) {1462const CacheUse = union(CacheMode) {
1463 none: *None,
1436 incremental: *Incremental,1464 incremental: *Incremental,
1437 whole: *Whole,1465 whole: *Whole,
14381466
1467 const None = struct {
1468 /// User-requested artifacts are written directly to their output path in this cache mode.
1469 /// However, if we need to emit any temporary files, they are placed in this directory.
1470 /// We will recursively delete this directory at the end of this update. This field is
1471 /// non-`null` only inside `update`.
1472 tmp_artifact_directory: ?Cache.Directory,
1473 };
1474
1475 const Incremental = struct {
1476 /// All output files, including artifacts and incremental compilation metadata, are placed
1477 /// in this directory, which is some 'o/<hash>' in a cache directory.
1478 artifact_directory: Cache.Directory,
1479 };
1480
1439 const Whole = struct {1481 const Whole = struct {
1440 /// This is a pointer to a local variable inside `update()`.1482 /// Since we don't open the output file until `update`, we must save these options for then.
1441 cache_manifest: ?*Cache.Manifest = null,
1442 cache_manifest_mutex: std.Thread.Mutex = .{},
1443 /// null means -fno-emit-bin.
1444 /// This is mutable memory allocated into the Compilation-lifetime arena (`arena`)
1445 /// of exactly the correct size for "o/[digest]/[basename]".
1446 /// The basename is of the outputted binary file in case we don't know the directory yet.
1447 bin_sub_path: ?[]u8,
1448 /// Same as `bin_sub_path` but for implibs.
1449 implib_sub_path: ?[]u8,
1450 docs_sub_path: ?[]u8,
1451 lf_open_opts: link.File.OpenOptions,1483 lf_open_opts: link.File.OpenOptions,
1484 /// This is a pointer to a local variable inside `update`.
1485 cache_manifest: ?*Cache.Manifest,
1486 cache_manifest_mutex: std.Thread.Mutex,
1487 /// This is non-`null` for most of the body of `update`. It is the temporary directory which
1488 /// we initially emit our artifacts to. After the main part of the update is done, it will
1489 /// be closed and moved to its final location, and this field set to `null`.
1452 tmp_artifact_directory: ?Cache.Directory,1490 tmp_artifact_directory: ?Cache.Directory,
1453 /// Prevents other processes from clobbering files in the output directory.1491 /// Prevents other processes from clobbering files in the output directory.
1454 lock: ?Cache.Lock,1492 lock: ?Cache.Lock,
...@@ -1467,17 +1505,16 @@ const CacheUse = union(CacheMode) {...@@ -1467,17 +1505,16 @@ const CacheUse = union(CacheMode) {
1467 }1505 }
1468 };1506 };
14691507
1470 const Incremental = struct {
1471 /// Where build artifacts and incremental compilation metadata serialization go.
1472 artifact_directory: Cache.Directory,
1473 };
1474
1475 fn deinit(cu: CacheUse) void {1508 fn deinit(cu: CacheUse) void {
1476 switch (cu) {1509 switch (cu) {
1510 .none => |none| {
1511 assert(none.tmp_artifact_directory == null);
1512 },
1477 .incremental => |incremental| {1513 .incremental => |incremental| {
1478 incremental.artifact_directory.handle.close();1514 incremental.artifact_directory.handle.close();
1479 },1515 },
1480 .whole => |whole| {1516 .whole => |whole| {
1517 assert(whole.tmp_artifact_directory == null);
1481 whole.releaseLock();1518 whole.releaseLock();
1482 },1519 },
1483 }1520 }
...@@ -1504,28 +1541,14 @@ pub const CreateOptions = struct {...@@ -1504,28 +1541,14 @@ pub const CreateOptions = struct {
1504 std_mod: ?*Package.Module = null,1541 std_mod: ?*Package.Module = null,
1505 root_name: []const u8,1542 root_name: []const u8,
1506 sysroot: ?[]const u8 = null,1543 sysroot: ?[]const u8 = null,
1507 /// `null` means to not emit a binary file.1544 cache_mode: CacheMode,
1508 emit_bin: ?EmitLoc,1545 emit_h: Emit = .no,
1509 /// `null` means to not emit a C header file.1546 emit_bin: Emit,
1510 emit_h: ?EmitLoc = null,1547 emit_asm: Emit = .no,
1511 /// `null` means to not emit assembly.1548 emit_implib: Emit = .no,
1512 emit_asm: ?EmitLoc = null,1549 emit_llvm_ir: Emit = .no,
1513 /// `null` means to not emit LLVM IR.1550 emit_llvm_bc: Emit = .no,
1514 emit_llvm_ir: ?EmitLoc = null,1551 emit_docs: Emit = .no,
1515 /// `null` means to not emit LLVM module bitcode.
1516 emit_llvm_bc: ?EmitLoc = null,
1517 /// `null` means to not emit docs.
1518 emit_docs: ?EmitLoc = null,
1519 /// `null` means to not emit an import lib.
1520 emit_implib: ?EmitLoc = null,
1521 /// Normally when using LLD to link, Zig uses a file named "lld.id" in the
1522 /// same directory as the output binary which contains the hash of the link
1523 /// operation, allowing Zig to skip linking when the hash would be unchanged.
1524 /// In the case that the output binary is being emitted into a directory which
1525 /// is externally modified - essentially anything other than zig-cache - then
1526 /// this flag would be set to disable this machinery to avoid false positives.
1527 disable_lld_caching: bool = false,
1528 cache_mode: CacheMode = .incremental,
1529 /// This field is intended to be removed.1552 /// This field is intended to be removed.
1530 /// The ELF implementation no longer uses this data, however the MachO and COFF1553 /// The ELF implementation no longer uses this data, however the MachO and COFF
1531 /// implementations still do.1554 /// implementations still do.
...@@ -1591,9 +1614,9 @@ pub const CreateOptions = struct {...@@ -1591,9 +1614,9 @@ pub const CreateOptions = struct {
1591 linker_tsaware: bool = false,1614 linker_tsaware: bool = false,
1592 linker_nxcompat: bool = false,1615 linker_nxcompat: bool = false,
1593 linker_dynamicbase: bool = true,1616 linker_dynamicbase: bool = true,
1594 linker_compress_debug_sections: ?link.File.Elf.CompressDebugSections = null,1617 linker_compress_debug_sections: ?link.File.Lld.Elf.CompressDebugSections = null,
1595 linker_module_definition_file: ?[]const u8 = null,1618 linker_module_definition_file: ?[]const u8 = null,
1596 linker_sort_section: ?link.File.Elf.SortSection = null,1619 linker_sort_section: ?link.File.Lld.Elf.SortSection = null,
1597 major_subsystem_version: ?u16 = null,1620 major_subsystem_version: ?u16 = null,
1598 minor_subsystem_version: ?u16 = null,1621 minor_subsystem_version: ?u16 = null,
1599 clang_passthrough_mode: bool = false,1622 clang_passthrough_mode: bool = false,
...@@ -1615,7 +1638,7 @@ pub const CreateOptions = struct {...@@ -1615,7 +1638,7 @@ pub const CreateOptions = struct {
1615 /// building such dependencies themselves, this flag must be set to avoid1638 /// building such dependencies themselves, this flag must be set to avoid
1616 /// infinite recursion.1639 /// infinite recursion.
1617 skip_linker_dependencies: bool = false,1640 skip_linker_dependencies: bool = false,
1618 hash_style: link.File.Elf.HashStyle = .both,1641 hash_style: link.File.Lld.Elf.HashStyle = .both,
1619 entry: Entry = .default,1642 entry: Entry = .default,
1620 force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .empty,1643 force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .empty,
1621 stack_size: ?u64 = null,1644 stack_size: ?u64 = null,
...@@ -1663,6 +1686,38 @@ pub const CreateOptions = struct {...@@ -1663,6 +1686,38 @@ pub const CreateOptions = struct {
1663 parent_whole_cache: ?ParentWholeCache = null,1686 parent_whole_cache: ?ParentWholeCache = null,
16641687
1665 pub const Entry = link.File.OpenOptions.Entry;1688 pub const Entry = link.File.OpenOptions.Entry;
1689
1690 /// Which fields are valid depends on the `cache_mode` given.
1691 pub const Emit = union(enum) {
1692 /// Do not emit this file. Always valid.
1693 no,
1694 /// Emit this file into its default name in the cache directory.
1695 /// Requires `cache_mode` to not be `.none`.
1696 yes_cache,
1697 /// Emit this file to the given path (absolute or cwd-relative).
1698 /// Requires `cache_mode` to be `.none`.
1699 yes_path: []const u8,
1700
1701 fn resolve(emit: Emit, arena: Allocator, opts: *const CreateOptions, ea: std.zig.EmitArtifact) Allocator.Error!?[]const u8 {
1702 switch (emit) {
1703 .no => return null,
1704 .yes_cache => {
1705 assert(opts.cache_mode != .none);
1706 return try ea.cacheName(arena, .{
1707 .root_name = opts.root_name,
1708 .target = opts.root_mod.resolved_target.result,
1709 .output_mode = opts.config.output_mode,
1710 .link_mode = opts.config.link_mode,
1711 .version = opts.version,
1712 });
1713 },
1714 .yes_path => |path| {
1715 assert(opts.cache_mode == .none);
1716 return try arena.dupe(u8, path);
1717 },
1718 }
1719 }
1720 };
1666};1721};
16671722
1668fn addModuleTableToCacheHash(1723fn addModuleTableToCacheHash(
...@@ -1870,13 +1925,18 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1870,13 +1925,18 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1870 cache.hash.add(options.config.link_libunwind);1925 cache.hash.add(options.config.link_libunwind);
1871 cache.hash.add(output_mode);1926 cache.hash.add(output_mode);
1872 cache_helpers.addDebugFormat(&cache.hash, options.config.debug_format);1927 cache_helpers.addDebugFormat(&cache.hash, options.config.debug_format);
1873 cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_bin);
1874 cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_implib);
1875 cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_docs);
1876 cache.hash.addBytes(options.root_name);1928 cache.hash.addBytes(options.root_name);
1877 cache.hash.add(options.config.wasi_exec_model);1929 cache.hash.add(options.config.wasi_exec_model);
1878 cache.hash.add(options.config.san_cov_trace_pc_guard);1930 cache.hash.add(options.config.san_cov_trace_pc_guard);
1879 cache.hash.add(options.debug_compiler_runtime_libs);1931 cache.hash.add(options.debug_compiler_runtime_libs);
1932 // The actual emit paths don't matter. They're only user-specified if we aren't using the
1933 // cache! However, it does matter whether the files are emitted at all.
1934 cache.hash.add(options.emit_bin != .no);
1935 cache.hash.add(options.emit_asm != .no);
1936 cache.hash.add(options.emit_implib != .no);
1937 cache.hash.add(options.emit_llvm_ir != .no);
1938 cache.hash.add(options.emit_llvm_bc != .no);
1939 cache.hash.add(options.emit_docs != .no);
1880 // TODO audit this and make sure everything is in it1940 // TODO audit this and make sure everything is in it
18811941
1882 const main_mod = options.main_mod orelse options.root_mod;1942 const main_mod = options.main_mod orelse options.root_mod;
...@@ -1926,7 +1986,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1926,7 +1986,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1926 try zcu.init(options.thread_pool.getIdCount());1986 try zcu.init(options.thread_pool.getIdCount());
1927 break :blk zcu;1987 break :blk zcu;
1928 } else blk: {1988 } else blk: {
1929 if (options.emit_h != null) return error.NoZigModuleForCHeader;1989 if (options.emit_h != .no) return error.NoZigModuleForCHeader;
1930 break :blk null;1990 break :blk null;
1931 };1991 };
1932 errdefer if (opt_zcu) |zcu| zcu.deinit();1992 errdefer if (opt_zcu) |zcu| zcu.deinit();
...@@ -1939,18 +1999,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1939,18 +1999,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1939 .arena = arena,1999 .arena = arena,
1940 .zcu = opt_zcu,2000 .zcu = opt_zcu,
1941 .cache_use = undefined, // populated below2001 .cache_use = undefined, // populated below
1942 .bin_file = null, // populated below2002 .bin_file = null, // populated below if necessary
1943 .implib_emit = null, // handled below
1944 .docs_emit = null, // handled below
1945 .root_mod = options.root_mod,2003 .root_mod = options.root_mod,
1946 .config = options.config,2004 .config = options.config,
1947 .dirs = options.dirs,2005 .dirs = options.dirs,
1948 .emit_asm = options.emit_asm,
1949 .emit_llvm_ir = options.emit_llvm_ir,
1950 .emit_llvm_bc = options.emit_llvm_bc,
1951 .work_queues = @splat(.init(gpa)),2006 .work_queues = @splat(.init(gpa)),
1952 .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa),2007 .c_object_work_queue = .init(gpa),
1953 .win32_resource_work_queue = if (dev.env.supports(.win32_resource)) std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa) else .{},2008 .win32_resource_work_queue = if (dev.env.supports(.win32_resource)) .init(gpa) else .{},
1954 .c_source_files = options.c_source_files,2009 .c_source_files = options.c_source_files,
1955 .rc_source_files = options.rc_source_files,2010 .rc_source_files = options.rc_source_files,
1956 .cache_parent = cache,2011 .cache_parent = cache,
...@@ -2003,7 +2058,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2003,7 +2058,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2003 .file_system_inputs = options.file_system_inputs,2058 .file_system_inputs = options.file_system_inputs,
2004 .parent_whole_cache = options.parent_whole_cache,2059 .parent_whole_cache = options.parent_whole_cache,
2005 .link_diags = .init(gpa),2060 .link_diags = .init(gpa),
2006 .remaining_prelink_tasks = 0,2061 .emit_bin = try options.emit_bin.resolve(arena, &options, .bin),
2062 .emit_asm = try options.emit_asm.resolve(arena, &options, .@"asm"),
2063 .emit_implib = try options.emit_implib.resolve(arena, &options, .implib),
2064 .emit_llvm_ir = try options.emit_llvm_ir.resolve(arena, &options, .llvm_ir),
2065 .emit_llvm_bc = try options.emit_llvm_bc.resolve(arena, &options, .llvm_bc),
2066 .emit_docs = try options.emit_docs.resolve(arena, &options, .docs),
2007 };2067 };
20082068
2009 // Prevent some footguns by making the "any" fields of config reflect2069 // Prevent some footguns by making the "any" fields of config reflect
...@@ -2070,7 +2130,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2070,7 +2130,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2070 .soname = options.soname,2130 .soname = options.soname,
2071 .compatibility_version = options.compatibility_version,2131 .compatibility_version = options.compatibility_version,
2072 .build_id = build_id,2132 .build_id = build_id,
2073 .disable_lld_caching = options.disable_lld_caching or options.cache_mode == .whole,
2074 .subsystem = options.subsystem,2133 .subsystem = options.subsystem,
2075 .hash_style = options.hash_style,2134 .hash_style = options.hash_style,
2076 .enable_link_snapshots = options.enable_link_snapshots,2135 .enable_link_snapshots = options.enable_link_snapshots,
...@@ -2089,6 +2148,17 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2089,6 +2148,17 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2089 };2148 };
20902149
2091 switch (options.cache_mode) {2150 switch (options.cache_mode) {
2151 .none => {
2152 const none = try arena.create(CacheUse.None);
2153 none.* = .{ .tmp_artifact_directory = null };
2154 comp.cache_use = .{ .none = none };
2155 if (comp.emit_bin) |path| {
2156 comp.bin_file = try link.File.open(arena, comp, .{
2157 .root_dir = .cwd(),
2158 .sub_path = path,
2159 }, lf_open_opts);
2160 }
2161 },
2092 .incremental => {2162 .incremental => {
2093 // Options that are specific to zig source files, that cannot be2163 // Options that are specific to zig source files, that cannot be
2094 // modified between incremental updates.2164 // modified between incremental updates.
...@@ -2102,7 +2172,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2102,7 +2172,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2102 hash.addListOfBytes(options.test_filters);2172 hash.addListOfBytes(options.test_filters);
2103 hash.addOptionalBytes(options.test_name_prefix);2173 hash.addOptionalBytes(options.test_name_prefix);
2104 hash.add(options.skip_linker_dependencies);2174 hash.add(options.skip_linker_dependencies);
2105 hash.add(options.emit_h != null);2175 hash.add(options.emit_h != .no);
2106 hash.add(error_limit);2176 hash.add(error_limit);
21072177
2108 // Here we put the root source file path name, but *not* with addFile.2178 // Here we put the root source file path name, but *not* with addFile.
...@@ -2137,49 +2207,26 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2137,49 +2207,26 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2137 };2207 };
2138 comp.cache_use = .{ .incremental = incremental };2208 comp.cache_use = .{ .incremental = incremental };
21392209
2140 if (options.emit_bin) |emit_bin| {2210 if (comp.emit_bin) |cache_rel_path| {
2141 const emit: Cache.Path = .{2211 const emit: Cache.Path = .{
2142 .root_dir = emit_bin.directory orelse artifact_directory,2212 .root_dir = artifact_directory,
2143 .sub_path = emit_bin.basename,2213 .sub_path = cache_rel_path,
2144 };2214 };
2145 comp.bin_file = try link.File.open(arena, comp, emit, lf_open_opts);2215 comp.bin_file = try link.File.open(arena, comp, emit, lf_open_opts);
2146 }2216 }
2147
2148 if (options.emit_implib) |emit_implib| {
2149 comp.implib_emit = .{
2150 .root_dir = emit_implib.directory orelse artifact_directory,
2151 .sub_path = emit_implib.basename,
2152 };
2153 }
2154
2155 if (options.emit_docs) |emit_docs| {
2156 comp.docs_emit = .{
2157 .root_dir = emit_docs.directory orelse artifact_directory,
2158 .sub_path = emit_docs.basename,
2159 };
2160 }
2161 },2217 },
2162 .whole => {2218 .whole => {
2163 // For whole cache mode, we don't know where to put outputs from2219 // For whole cache mode, we don't know where to put outputs from the linker until
2164 // the linker until the final cache hash, which is available after2220 // the final cache hash, which is available after the compilation is complete.
2165 // the compilation is complete.
2166 //2221 //
2167 // Therefore, bin_file is left null until the beginning of update(),2222 // Therefore, `comp.bin_file` is left `null` (already done) until `update`, where
2168 // where it may find a cache hit, or use a temporary directory to2223 // it may find a cache hit, or else will use a temporary directory to hold output
2169 // hold output artifacts.2224 // artifacts.
2170 const whole = try arena.create(CacheUse.Whole);2225 const whole = try arena.create(CacheUse.Whole);
2171 whole.* = .{2226 whole.* = .{
2172 // This is kept here so that link.File.open can be called later.
2173 .lf_open_opts = lf_open_opts,2227 .lf_open_opts = lf_open_opts,
2174 // This is so that when doing `CacheMode.whole`, the mechanism in update()2228 .cache_manifest = null,
2175 // can use it for communicating the result directory via `bin_file.emit`.2229 .cache_manifest_mutex = .{},
2176 // This is used to distinguish between -fno-emit-bin and -femit-bin
2177 // for `CacheMode.whole`.
2178 // This memory will be overwritten with the real digest in update() but
2179 // the basename will be preserved.
2180 .bin_sub_path = try prepareWholeEmitSubPath(arena, options.emit_bin),
2181 .implib_sub_path = try prepareWholeEmitSubPath(arena, options.emit_implib),
2182 .docs_sub_path = try prepareWholeEmitSubPath(arena, options.emit_docs),
2183 .tmp_artifact_directory = null,2230 .tmp_artifact_directory = null,
2184 .lock = null,2231 .lock = null,
2185 };2232 };
...@@ -2187,14 +2234,10 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2187,14 +2234,10 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2187 },2234 },
2188 }2235 }
21892236
2190 // Handle the case of e.g. -fno-emit-bin -femit-llvm-ir.2237 if (use_llvm) {
2191 if (options.emit_bin == null and (comp.verbose_llvm_ir != null or2238 if (opt_zcu) |zcu| {
2192 comp.verbose_llvm_bc != null or2239 zcu.llvm_object = try LlvmObject.create(arena, comp);
2193 (use_llvm and comp.emit_asm != null) or2240 }
2194 comp.emit_llvm_ir != null or
2195 comp.emit_llvm_bc != null))
2196 {
2197 if (opt_zcu) |zcu| zcu.llvm_object = try LlvmObject.create(arena, comp);
2198 }2241 }
21992242
2200 break :comp comp;2243 break :comp comp;
...@@ -2216,7 +2259,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2216,7 +2259,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2216 };2259 };
2217 comp.c_object_table.putAssumeCapacityNoClobber(c_object, {});2260 comp.c_object_table.putAssumeCapacityNoClobber(c_object, {});
2218 }2261 }
2219 comp.remaining_prelink_tasks += @intCast(comp.c_object_table.count());2262 comp.link_task_queue.pending_prelink_tasks += @intCast(comp.c_object_table.count());
22202263
2221 // Add a `Win32Resource` for each `rc_source_files` and one for `manifest_file`.2264 // Add a `Win32Resource` for each `rc_source_files` and one for `manifest_file`.
2222 const win32_resource_count =2265 const win32_resource_count =
...@@ -2227,7 +2270,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2227,7 +2270,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2227 // Add this after adding logic to updateWin32Resource to pass the2270 // Add this after adding logic to updateWin32Resource to pass the
2228 // result into link.loadInput. loadInput integration is not implemented2271 // result into link.loadInput. loadInput integration is not implemented
2229 // for Windows linking logic yet.2272 // for Windows linking logic yet.
2230 //comp.remaining_prelink_tasks += @intCast(win32_resource_count);2273 //comp.link_task_queue.pending_prelink_tasks += @intCast(win32_resource_count);
2231 for (options.rc_source_files) |rc_source_file| {2274 for (options.rc_source_files) |rc_source_file| {
2232 const win32_resource = try gpa.create(Win32Resource);2275 const win32_resource = try gpa.create(Win32Resource);
2233 errdefer gpa.destroy(win32_resource);2276 errdefer gpa.destroy(win32_resource);
...@@ -2251,12 +2294,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2251,12 +2294,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2251 }2294 }
2252 }2295 }
22532296
2254 const have_bin_emit = switch (comp.cache_use) {2297 if (comp.emit_bin != null and target.ofmt != .c) {
2255 .whole => |whole| whole.bin_sub_path != null,
2256 .incremental => comp.bin_file != null,
2257 };
2258
2259 if (have_bin_emit and target.ofmt != .c) {
2260 if (!comp.skip_linker_dependencies) {2298 if (!comp.skip_linker_dependencies) {
2261 // If we need to build libc for the target, add work items for it.2299 // If we need to build libc for the target, add work items for it.
2262 // We go through the work queue so that building can be done in parallel.2300 // We go through the work queue so that building can be done in parallel.
...@@ -2278,78 +2316,76 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2278,78 +2316,76 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2278 const paths = try lci.resolveCrtPaths(arena, basenames, target);2316 const paths = try lci.resolveCrtPaths(arena, basenames, target);
22792317
2280 const fields = @typeInfo(@TypeOf(paths)).@"struct".fields;2318 const fields = @typeInfo(@TypeOf(paths)).@"struct".fields;
2281 try comp.link_task_queue.shared.ensureUnusedCapacity(gpa, fields.len + 1);2319 try comp.link_task_queue.queued_prelink.ensureUnusedCapacity(gpa, fields.len + 1);
2282 inline for (fields) |field| {2320 inline for (fields) |field| {
2283 if (@field(paths, field.name)) |path| {2321 if (@field(paths, field.name)) |path| {
2284 comp.link_task_queue.shared.appendAssumeCapacity(.{ .load_object = path });2322 comp.link_task_queue.queued_prelink.appendAssumeCapacity(.{ .load_object = path });
2285 comp.remaining_prelink_tasks += 1;
2286 }2323 }
2287 }2324 }
2288 // Loads the libraries provided by `target_util.libcFullLinkFlags(target)`.2325 // Loads the libraries provided by `target_util.libcFullLinkFlags(target)`.
2289 comp.link_task_queue.shared.appendAssumeCapacity(.load_host_libc);2326 comp.link_task_queue.queued_prelink.appendAssumeCapacity(.load_host_libc);
2290 comp.remaining_prelink_tasks += 1;
2291 } else if (target.isMuslLibC()) {2327 } else if (target.isMuslLibC()) {
2292 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;2328 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
22932329
2294 if (musl.needsCrt0(comp.config.output_mode, comp.config.link_mode, comp.config.pie)) |f| {2330 if (musl.needsCrt0(comp.config.output_mode, comp.config.link_mode, comp.config.pie)) |f| {
2295 comp.queued_jobs.musl_crt_file[@intFromEnum(f)] = true;2331 comp.queued_jobs.musl_crt_file[@intFromEnum(f)] = true;
2296 comp.remaining_prelink_tasks += 1;2332 comp.link_task_queue.pending_prelink_tasks += 1;
2297 }2333 }
2298 switch (comp.config.link_mode) {2334 switch (comp.config.link_mode) {
2299 .static => comp.queued_jobs.musl_crt_file[@intFromEnum(musl.CrtFile.libc_a)] = true,2335 .static => comp.queued_jobs.musl_crt_file[@intFromEnum(musl.CrtFile.libc_a)] = true,
2300 .dynamic => comp.queued_jobs.musl_crt_file[@intFromEnum(musl.CrtFile.libc_so)] = true,2336 .dynamic => comp.queued_jobs.musl_crt_file[@intFromEnum(musl.CrtFile.libc_so)] = true,
2301 }2337 }
2302 comp.remaining_prelink_tasks += 1;2338 comp.link_task_queue.pending_prelink_tasks += 1;
2303 } else if (target.isGnuLibC()) {2339 } else if (target.isGnuLibC()) {
2304 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;2340 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
23052341
2306 if (glibc.needsCrt0(comp.config.output_mode)) |f| {2342 if (glibc.needsCrt0(comp.config.output_mode)) |f| {
2307 comp.queued_jobs.glibc_crt_file[@intFromEnum(f)] = true;2343 comp.queued_jobs.glibc_crt_file[@intFromEnum(f)] = true;
2308 comp.remaining_prelink_tasks += 1;2344 comp.link_task_queue.pending_prelink_tasks += 1;
2309 }2345 }
2310 comp.queued_jobs.glibc_shared_objects = true;2346 comp.queued_jobs.glibc_shared_objects = true;
2311 comp.remaining_prelink_tasks += glibc.sharedObjectsCount(&target);2347 comp.link_task_queue.pending_prelink_tasks += glibc.sharedObjectsCount(&target);
23122348
2313 comp.queued_jobs.glibc_crt_file[@intFromEnum(glibc.CrtFile.libc_nonshared_a)] = true;2349 comp.queued_jobs.glibc_crt_file[@intFromEnum(glibc.CrtFile.libc_nonshared_a)] = true;
2314 comp.remaining_prelink_tasks += 1;2350 comp.link_task_queue.pending_prelink_tasks += 1;
2315 } else if (target.isFreeBSDLibC()) {2351 } else if (target.isFreeBSDLibC()) {
2316 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;2352 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
23172353
2318 if (freebsd.needsCrt0(comp.config.output_mode)) |f| {2354 if (freebsd.needsCrt0(comp.config.output_mode)) |f| {
2319 comp.queued_jobs.freebsd_crt_file[@intFromEnum(f)] = true;2355 comp.queued_jobs.freebsd_crt_file[@intFromEnum(f)] = true;
2320 comp.remaining_prelink_tasks += 1;2356 comp.link_task_queue.pending_prelink_tasks += 1;
2321 }2357 }
23222358
2323 comp.queued_jobs.freebsd_shared_objects = true;2359 comp.queued_jobs.freebsd_shared_objects = true;
2324 comp.remaining_prelink_tasks += freebsd.sharedObjectsCount();2360 comp.link_task_queue.pending_prelink_tasks += freebsd.sharedObjectsCount();
2325 } else if (target.isNetBSDLibC()) {2361 } else if (target.isNetBSDLibC()) {
2326 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;2362 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
23272363
2328 if (netbsd.needsCrt0(comp.config.output_mode)) |f| {2364 if (netbsd.needsCrt0(comp.config.output_mode)) |f| {
2329 comp.queued_jobs.netbsd_crt_file[@intFromEnum(f)] = true;2365 comp.queued_jobs.netbsd_crt_file[@intFromEnum(f)] = true;
2330 comp.remaining_prelink_tasks += 1;2366 comp.link_task_queue.pending_prelink_tasks += 1;
2331 }2367 }
23322368
2333 comp.queued_jobs.netbsd_shared_objects = true;2369 comp.queued_jobs.netbsd_shared_objects = true;
2334 comp.remaining_prelink_tasks += netbsd.sharedObjectsCount();2370 comp.link_task_queue.pending_prelink_tasks += netbsd.sharedObjectsCount();
2335 } else if (target.isWasiLibC()) {2371 } else if (target.isWasiLibC()) {
2336 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;2372 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
23372373
2338 for (comp.wasi_emulated_libs) |crt_file| {2374 for (comp.wasi_emulated_libs) |crt_file| {
2339 comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(crt_file)] = true;2375 comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(crt_file)] = true;
2340 }2376 }
2341 comp.remaining_prelink_tasks += @intCast(comp.wasi_emulated_libs.len);2377 comp.link_task_queue.pending_prelink_tasks += @intCast(comp.wasi_emulated_libs.len);
23422378
2343 comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(wasi_libc.execModelCrtFile(comp.config.wasi_exec_model))] = true;2379 comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(wasi_libc.execModelCrtFile(comp.config.wasi_exec_model))] = true;
2344 comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(wasi_libc.CrtFile.libc_a)] = true;2380 comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(wasi_libc.CrtFile.libc_a)] = true;
2345 comp.remaining_prelink_tasks += 2;2381 comp.link_task_queue.pending_prelink_tasks += 2;
2346 } else if (target.isMinGW()) {2382 } else if (target.isMinGW()) {
2347 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;2383 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
23482384
2349 const main_crt_file: mingw.CrtFile = if (is_dyn_lib) .dllcrt2_o else .crt2_o;2385 const main_crt_file: mingw.CrtFile = if (is_dyn_lib) .dllcrt2_o else .crt2_o;
2350 comp.queued_jobs.mingw_crt_file[@intFromEnum(main_crt_file)] = true;2386 comp.queued_jobs.mingw_crt_file[@intFromEnum(main_crt_file)] = true;
2351 comp.queued_jobs.mingw_crt_file[@intFromEnum(mingw.CrtFile.libmingw32_lib)] = true;2387 comp.queued_jobs.mingw_crt_file[@intFromEnum(mingw.CrtFile.libmingw32_lib)] = true;
2352 comp.remaining_prelink_tasks += 2;2388 comp.link_task_queue.pending_prelink_tasks += 2;
23532389
2354 // When linking mingw-w64 there are some import libs we always need.2390 // When linking mingw-w64 there are some import libs we always need.
2355 try comp.windows_libs.ensureUnusedCapacity(gpa, mingw.always_link_libs.len);2391 try comp.windows_libs.ensureUnusedCapacity(gpa, mingw.always_link_libs.len);
...@@ -2363,7 +2399,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2363,7 +2399,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2363 target.isMinGW())2399 target.isMinGW())
2364 {2400 {
2365 comp.queued_jobs.zigc_lib = true;2401 comp.queued_jobs.zigc_lib = true;
2366 comp.remaining_prelink_tasks += 1;2402 comp.link_task_queue.pending_prelink_tasks += 1;
2367 }2403 }
2368 }2404 }
23692405
...@@ -2380,53 +2416,53 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2380,53 +2416,53 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2380 }2416 }
2381 if (comp.wantBuildLibUnwindFromSource()) {2417 if (comp.wantBuildLibUnwindFromSource()) {
2382 comp.queued_jobs.libunwind = true;2418 comp.queued_jobs.libunwind = true;
2383 comp.remaining_prelink_tasks += 1;2419 comp.link_task_queue.pending_prelink_tasks += 1;
2384 }2420 }
2385 if (build_options.have_llvm and is_exe_or_dyn_lib and comp.config.link_libcpp) {2421 if (build_options.have_llvm and is_exe_or_dyn_lib and comp.config.link_libcpp) {
2386 comp.queued_jobs.libcxx = true;2422 comp.queued_jobs.libcxx = true;
2387 comp.queued_jobs.libcxxabi = true;2423 comp.queued_jobs.libcxxabi = true;
2388 comp.remaining_prelink_tasks += 2;2424 comp.link_task_queue.pending_prelink_tasks += 2;
2389 }2425 }
2390 if (build_options.have_llvm and is_exe_or_dyn_lib and comp.config.any_sanitize_thread) {2426 if (build_options.have_llvm and is_exe_or_dyn_lib and comp.config.any_sanitize_thread) {
2391 comp.queued_jobs.libtsan = true;2427 comp.queued_jobs.libtsan = true;
2392 comp.remaining_prelink_tasks += 1;2428 comp.link_task_queue.pending_prelink_tasks += 1;
2393 }2429 }
23942430
2395 if (can_build_compiler_rt) {2431 if (can_build_compiler_rt) {
2396 if (comp.compiler_rt_strat == .lib) {2432 if (comp.compiler_rt_strat == .lib) {
2397 log.debug("queuing a job to build compiler_rt_lib", .{});2433 log.debug("queuing a job to build compiler_rt_lib", .{});
2398 comp.queued_jobs.compiler_rt_lib = true;2434 comp.queued_jobs.compiler_rt_lib = true;
2399 comp.remaining_prelink_tasks += 1;2435 comp.link_task_queue.pending_prelink_tasks += 1;
2400 } else if (comp.compiler_rt_strat == .obj) {2436 } else if (comp.compiler_rt_strat == .obj) {
2401 log.debug("queuing a job to build compiler_rt_obj", .{});2437 log.debug("queuing a job to build compiler_rt_obj", .{});
2402 // In this case we are making a static library, so we ask2438 // In this case we are making a static library, so we ask
2403 // for a compiler-rt object to put in it.2439 // for a compiler-rt object to put in it.
2404 comp.queued_jobs.compiler_rt_obj = true;2440 comp.queued_jobs.compiler_rt_obj = true;
2405 comp.remaining_prelink_tasks += 1;2441 comp.link_task_queue.pending_prelink_tasks += 1;
2406 }2442 }
24072443
2408 if (comp.ubsan_rt_strat == .lib) {2444 if (comp.ubsan_rt_strat == .lib) {
2409 log.debug("queuing a job to build ubsan_rt_lib", .{});2445 log.debug("queuing a job to build ubsan_rt_lib", .{});
2410 comp.queued_jobs.ubsan_rt_lib = true;2446 comp.queued_jobs.ubsan_rt_lib = true;
2411 comp.remaining_prelink_tasks += 1;2447 comp.link_task_queue.pending_prelink_tasks += 1;
2412 } else if (comp.ubsan_rt_strat == .obj) {2448 } else if (comp.ubsan_rt_strat == .obj) {
2413 log.debug("queuing a job to build ubsan_rt_obj", .{});2449 log.debug("queuing a job to build ubsan_rt_obj", .{});
2414 comp.queued_jobs.ubsan_rt_obj = true;2450 comp.queued_jobs.ubsan_rt_obj = true;
2415 comp.remaining_prelink_tasks += 1;2451 comp.link_task_queue.pending_prelink_tasks += 1;
2416 }2452 }
24172453
2418 if (is_exe_or_dyn_lib and comp.config.any_fuzz) {2454 if (is_exe_or_dyn_lib and comp.config.any_fuzz) {
2419 log.debug("queuing a job to build libfuzzer", .{});2455 log.debug("queuing a job to build libfuzzer", .{});
2420 comp.queued_jobs.fuzzer_lib = true;2456 comp.queued_jobs.fuzzer_lib = true;
2421 comp.remaining_prelink_tasks += 1;2457 comp.link_task_queue.pending_prelink_tasks += 1;
2422 }2458 }
2423 }2459 }
2424 }2460 }
24252461
2426 try comp.link_task_queue.shared.append(gpa, .load_explicitly_provided);2462 try comp.link_task_queue.queued_prelink.append(gpa, .load_explicitly_provided);
2427 comp.remaining_prelink_tasks += 1;
2428 }2463 }
2429 log.debug("total prelink tasks: {d}", .{comp.remaining_prelink_tasks});2464 log.debug("queued prelink tasks: {d}", .{comp.link_task_queue.queued_prelink.items.len});
2465 log.debug("pending prelink tasks: {d}", .{comp.link_task_queue.pending_prelink_tasks});
24302466
2431 return comp;2467 return comp;
2432}2468}
...@@ -2434,6 +2470,10 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2434,6 +2470,10 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2434pub fn destroy(comp: *Compilation) void {2470pub fn destroy(comp: *Compilation) void {
2435 const gpa = comp.gpa;2471 const gpa = comp.gpa;
24362472
2473 // This needs to be destroyed first, because it might contain MIR which we only know
2474 // how to interpret (which kind of MIR it is) from `comp.bin_file`.
2475 comp.link_task_queue.deinit(comp);
2476
2437 if (comp.bin_file) |lf| lf.destroy();2477 if (comp.bin_file) |lf| lf.destroy();
2438 if (comp.zcu) |zcu| zcu.deinit();2478 if (comp.zcu) |zcu| zcu.deinit();
2439 comp.cache_use.deinit();2479 comp.cache_use.deinit();
...@@ -2515,8 +2555,6 @@ pub fn destroy(comp: *Compilation) void {...@@ -2515,8 +2555,6 @@ pub fn destroy(comp: *Compilation) void {
2515 comp.failed_win32_resources.deinit(gpa);2555 comp.failed_win32_resources.deinit(gpa);
25162556
2517 comp.link_diags.deinit();2557 comp.link_diags.deinit();
2518 comp.link_task_queue.deinit(gpa);
2519 comp.link_task_queue_postponed.deinit(gpa);
25202558
2521 comp.clearMiscFailures();2559 comp.clearMiscFailures();
25222560
...@@ -2550,8 +2588,28 @@ pub fn hotCodeSwap(...@@ -2550,8 +2588,28 @@ pub fn hotCodeSwap(
2550 try lf.makeExecutable();2588 try lf.makeExecutable();
2551}2589}
25522590
2553fn cleanupAfterUpdate(comp: *Compilation) void {2591fn cleanupAfterUpdate(comp: *Compilation, tmp_dir_rand_int: u64) void {
2554 switch (comp.cache_use) {2592 switch (comp.cache_use) {
2593 .none => |none| {
2594 if (none.tmp_artifact_directory) |*tmp_dir| {
2595 tmp_dir.handle.close();
2596 none.tmp_artifact_directory = null;
2597 if (dev.env == .bootstrap) {
2598 // zig1 uses `CacheMode.none`, but it doesn't need to know how to delete
2599 // temporary directories; it doesn't have a real cache directory anyway.
2600 return;
2601 }
2602 const tmp_dir_sub_path = "tmp" ++ std.fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int);
2603 comp.dirs.local_cache.handle.deleteTree(tmp_dir_sub_path) catch |err| {
2604 log.warn("failed to delete temporary directory '{s}{c}{s}': {s}", .{
2605 comp.dirs.local_cache.path orelse ".",
2606 std.fs.path.sep,
2607 tmp_dir_sub_path,
2608 @errorName(err),
2609 });
2610 };
2611 }
2612 },
2555 .incremental => return,2613 .incremental => return,
2556 .whole => |whole| {2614 .whole => |whole| {
2557 if (whole.cache_manifest) |man| {2615 if (whole.cache_manifest) |man| {
...@@ -2562,10 +2620,18 @@ fn cleanupAfterUpdate(comp: *Compilation) void {...@@ -2562,10 +2620,18 @@ fn cleanupAfterUpdate(comp: *Compilation) void {
2562 lf.destroy();2620 lf.destroy();
2563 comp.bin_file = null;2621 comp.bin_file = null;
2564 }2622 }
2565 if (whole.tmp_artifact_directory) |*directory| {2623 if (whole.tmp_artifact_directory) |*tmp_dir| {
2566 directory.handle.close();2624 tmp_dir.handle.close();
2567 if (directory.path) |p| comp.gpa.free(p);
2568 whole.tmp_artifact_directory = null;2625 whole.tmp_artifact_directory = null;
2626 const tmp_dir_sub_path = "tmp" ++ std.fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int);
2627 comp.dirs.local_cache.handle.deleteTree(tmp_dir_sub_path) catch |err| {
2628 log.warn("failed to delete temporary directory '{s}{c}{s}': {s}", .{
2629 comp.dirs.local_cache.path orelse ".",
2630 std.fs.path.sep,
2631 tmp_dir_sub_path,
2632 @errorName(err),
2633 });
2634 };
2569 }2635 }
2570 },2636 },
2571 }2637 }
...@@ -2585,14 +2651,27 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2585,14 +2651,27 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2585 comp.clearMiscFailures();2651 comp.clearMiscFailures();
2586 comp.last_update_was_cache_hit = false;2652 comp.last_update_was_cache_hit = false;
25872653
2588 var man: Cache.Manifest = undefined;
2589 defer cleanupAfterUpdate(comp);
2590
2591 var tmp_dir_rand_int: u64 = undefined;2654 var tmp_dir_rand_int: u64 = undefined;
2655 var man: Cache.Manifest = undefined;
2656 defer cleanupAfterUpdate(comp, tmp_dir_rand_int);
25922657
2593 // If using the whole caching strategy, we check for *everything* up front, including2658 // If using the whole caching strategy, we check for *everything* up front, including
2594 // C source files.2659 // C source files.
2660 log.debug("Compilation.update for {s}, CacheMode.{s}", .{ comp.root_name, @tagName(comp.cache_use) });
2595 switch (comp.cache_use) {2661 switch (comp.cache_use) {
2662 .none => |none| {
2663 assert(none.tmp_artifact_directory == null);
2664 none.tmp_artifact_directory = d: {
2665 tmp_dir_rand_int = std.crypto.random.int(u64);
2666 const tmp_dir_sub_path = "tmp" ++ std.fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int);
2667 const path = try comp.dirs.local_cache.join(arena, &.{tmp_dir_sub_path});
2668 break :d .{
2669 .path = path,
2670 .handle = try comp.dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}),
2671 };
2672 };
2673 },
2674 .incremental => {},
2596 .whole => |whole| {2675 .whole => |whole| {
2597 assert(comp.bin_file == null);2676 assert(comp.bin_file == null);
2598 // We are about to obtain this lock, so here we give other processes a chance first.2677 // We are about to obtain this lock, so here we give other processes a chance first.
...@@ -2639,10 +2718,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2639,10 +2718,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2639 comp.last_update_was_cache_hit = true;2718 comp.last_update_was_cache_hit = true;
2640 log.debug("CacheMode.whole cache hit for {s}", .{comp.root_name});2719 log.debug("CacheMode.whole cache hit for {s}", .{comp.root_name});
2641 const bin_digest = man.finalBin();2720 const bin_digest = man.finalBin();
2642 const hex_digest = Cache.binToHex(bin_digest);
26432721
2644 comp.digest = bin_digest;2722 comp.digest = bin_digest;
2645 comp.wholeCacheModeSetBinFilePath(whole, &hex_digest);
26462723
2647 assert(whole.lock == null);2724 assert(whole.lock == null);
2648 whole.lock = man.toOwnedLock();2725 whole.lock = man.toOwnedLock();
...@@ -2651,52 +2728,23 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2651,52 +2728,23 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2651 log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name});2728 log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name});
26522729
2653 // Compile the artifacts to a temporary directory.2730 // Compile the artifacts to a temporary directory.
2654 const tmp_artifact_directory: Cache.Directory = d: {2731 whole.tmp_artifact_directory = d: {
2655 const s = std.fs.path.sep_str;
2656 tmp_dir_rand_int = std.crypto.random.int(u64);2732 tmp_dir_rand_int = std.crypto.random.int(u64);
2657 const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int);2733 const tmp_dir_sub_path = "tmp" ++ std.fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int);
26582734 const path = try comp.dirs.local_cache.join(arena, &.{tmp_dir_sub_path});
2659 const path = try comp.dirs.local_cache.join(gpa, &.{tmp_dir_sub_path});
2660 errdefer gpa.free(path);
2661
2662 const handle = try comp.dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{});
2663 errdefer handle.close();
2664
2665 break :d .{2735 break :d .{
2666 .path = path,2736 .path = path,
2667 .handle = handle,2737 .handle = try comp.dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}),
2668 };2738 };
2669 };2739 };
2670 whole.tmp_artifact_directory = tmp_artifact_directory;2740 if (comp.emit_bin) |sub_path| {
2671
2672 // Now that the directory is known, it is time to create the Emit
2673 // objects and call link.File.open.
2674
2675 if (whole.implib_sub_path) |sub_path| {
2676 comp.implib_emit = .{
2677 .root_dir = tmp_artifact_directory,
2678 .sub_path = std.fs.path.basename(sub_path),
2679 };
2680 }
2681
2682 if (whole.docs_sub_path) |sub_path| {
2683 comp.docs_emit = .{
2684 .root_dir = tmp_artifact_directory,
2685 .sub_path = std.fs.path.basename(sub_path),
2686 };
2687 }
2688
2689 if (whole.bin_sub_path) |sub_path| {
2690 const emit: Cache.Path = .{2741 const emit: Cache.Path = .{
2691 .root_dir = tmp_artifact_directory,2742 .root_dir = whole.tmp_artifact_directory.?,
2692 .sub_path = std.fs.path.basename(sub_path),2743 .sub_path = sub_path,
2693 };2744 };
2694 comp.bin_file = try link.File.createEmpty(arena, comp, emit, whole.lf_open_opts);2745 comp.bin_file = try link.File.createEmpty(arena, comp, emit, whole.lf_open_opts);
2695 }2746 }
2696 },2747 },
2697 .incremental => {
2698 log.debug("Compilation.update for {s}, CacheMode.incremental", .{comp.root_name});
2699 },
2700 }2748 }
27012749
2702 // From this point we add a preliminary set of file system inputs that2750 // From this point we add a preliminary set of file system inputs that
...@@ -2757,6 +2805,17 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2757,6 +2805,17 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2757 }2805 }
2758 }2806 }
27592807
2808 // The linker progress node is set up here instead of in `performAllTheWork`, because
2809 // we also want it around during `flush`.
2810 const have_link_node = comp.bin_file != null;
2811 if (have_link_node) {
2812 comp.link_prog_node = main_progress_node.start("Linking", 0);
2813 }
2814 defer if (have_link_node) {
2815 comp.link_prog_node.end();
2816 comp.link_prog_node = .none;
2817 };
2818
2760 try comp.performAllTheWork(main_progress_node);2819 try comp.performAllTheWork(main_progress_node);
27612820
2762 if (comp.zcu) |zcu| {2821 if (comp.zcu) |zcu| {
...@@ -2768,7 +2827,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2768,7 +2827,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2768 // The `test_functions` decl has been intentionally postponed until now,2827 // The `test_functions` decl has been intentionally postponed until now,
2769 // at which point we must populate it with the list of test functions that2828 // at which point we must populate it with the list of test functions that
2770 // have been discovered and not filtered out.2829 // have been discovered and not filtered out.
2771 try pt.populateTestFunctions(main_progress_node);2830 try pt.populateTestFunctions();
2772 }2831 }
27732832
2774 try pt.processExports();2833 try pt.processExports();
...@@ -2795,11 +2854,18 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2795,11 +2854,18 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2795 return;2854 return;
2796 }2855 }
27972856
2798 // Flush below handles -femit-bin but there is still -femit-llvm-ir,2857 if (comp.zcu == null and comp.config.output_mode == .Obj and comp.c_object_table.count() == 1) {
2799 // -femit-llvm-bc, and -femit-asm, in the case of C objects.2858 // This is `zig build-obj foo.c`. We can emit asm and LLVM IR/bitcode.
2800 comp.emitOthers();2859 const c_obj_path = comp.c_object_table.keys()[0].status.success.object_path;
2860 if (comp.emit_asm) |path| try comp.emitFromCObject(arena, c_obj_path, ".s", path);
2861 if (comp.emit_llvm_ir) |path| try comp.emitFromCObject(arena, c_obj_path, ".ll", path);
2862 if (comp.emit_llvm_bc) |path| try comp.emitFromCObject(arena, c_obj_path, ".bc", path);
2863 }
28012864
2802 switch (comp.cache_use) {2865 switch (comp.cache_use) {
2866 .none, .incremental => {
2867 try flush(comp, arena, .main);
2868 },
2803 .whole => |whole| {2869 .whole => |whole| {
2804 if (comp.file_system_inputs) |buf| try man.populateFileSystemInputs(buf);2870 if (comp.file_system_inputs) |buf| try man.populateFileSystemInputs(buf);
2805 if (comp.parent_whole_cache) |pwc| {2871 if (comp.parent_whole_cache) |pwc| {
...@@ -2811,18 +2877,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2811,18 +2877,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2811 const bin_digest = man.finalBin();2877 const bin_digest = man.finalBin();
2812 const hex_digest = Cache.binToHex(bin_digest);2878 const hex_digest = Cache.binToHex(bin_digest);
28132879
2814 // Rename the temporary directory into place.
2815 // Close tmp dir and link.File to avoid open handle during rename.
2816 if (whole.tmp_artifact_directory) |*tmp_directory| {
2817 tmp_directory.handle.close();
2818 if (tmp_directory.path) |p| gpa.free(p);
2819 whole.tmp_artifact_directory = null;
2820 } else unreachable;
2821
2822 const s = std.fs.path.sep_str;
2823 const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int);
2824 const o_sub_path = "o" ++ s ++ hex_digest;
2825
2826 // Work around windows `AccessDenied` if any files within this2880 // Work around windows `AccessDenied` if any files within this
2827 // directory are open by closing and reopening the file handles.2881 // directory are open by closing and reopening the file handles.
2828 const need_writable_dance: enum { no, lf_only, lf_and_debug } = w: {2882 const need_writable_dance: enum { no, lf_only, lf_and_debug } = w: {
...@@ -2847,6 +2901,13 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2847,6 +2901,13 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2847 break :w .no;2901 break :w .no;
2848 };2902 };
28492903
2904 // Rename the temporary directory into place.
2905 // Close tmp dir and link.File to avoid open handle during rename.
2906 whole.tmp_artifact_directory.?.handle.close();
2907 whole.tmp_artifact_directory = null;
2908 const s = std.fs.path.sep_str;
2909 const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int);
2910 const o_sub_path = "o" ++ s ++ hex_digest;
2850 renameTmpIntoCache(comp.dirs.local_cache, tmp_dir_sub_path, o_sub_path) catch |err| {2911 renameTmpIntoCache(comp.dirs.local_cache, tmp_dir_sub_path, o_sub_path) catch |err| {
2851 return comp.setMiscFailure(2912 return comp.setMiscFailure(
2852 .rename_results,2913 .rename_results,
...@@ -2859,7 +2920,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2859,7 +2920,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2859 );2920 );
2860 };2921 };
2861 comp.digest = bin_digest;2922 comp.digest = bin_digest;
2862 comp.wholeCacheModeSetBinFilePath(whole, &hex_digest);
28632923
2864 // The linker flush functions need to know the final output path2924 // The linker flush functions need to know the final output path
2865 // for debug info purposes because executable debug info contains2925 // for debug info purposes because executable debug info contains
...@@ -2867,10 +2927,9 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2867,10 +2927,9 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2867 if (comp.bin_file) |lf| {2927 if (comp.bin_file) |lf| {
2868 lf.emit = .{2928 lf.emit = .{
2869 .root_dir = comp.dirs.local_cache,2929 .root_dir = comp.dirs.local_cache,
2870 .sub_path = whole.bin_sub_path.?,2930 .sub_path = try std.fs.path.join(arena, &.{ o_sub_path, comp.emit_bin.? }),
2871 };2931 };
28722932
2873 // Has to be after the `wholeCacheModeSetBinFilePath` above.
2874 switch (need_writable_dance) {2933 switch (need_writable_dance) {
2875 .no => {},2934 .no => {},
2876 .lf_only => try lf.makeWritable(),2935 .lf_only => try lf.makeWritable(),
...@@ -2881,10 +2940,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2881,10 +2940,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2881 }2940 }
2882 }2941 }
28832942
2884 try flush(comp, arena, .{2943 try flush(comp, arena, .main);
2885 .root_dir = comp.dirs.local_cache,
2886 .sub_path = o_sub_path,
2887 }, .main, main_progress_node);
28882944
2889 // Calling `flush` may have produced errors, in which case the2945 // Calling `flush` may have produced errors, in which case the
2890 // cache manifest must not be written.2946 // cache manifest must not be written.
...@@ -2903,11 +2959,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2903,11 +2959,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2903 assert(whole.lock == null);2959 assert(whole.lock == null);
2904 whole.lock = man.toOwnedLock();2960 whole.lock = man.toOwnedLock();
2905 },2961 },
2906 .incremental => |incremental| {
2907 try flush(comp, arena, .{
2908 .root_dir = incremental.artifact_directory,
2909 }, .main, main_progress_node);
2910 },
2911 }2962 }
2912}2963}
29132964
...@@ -2937,27 +2988,98 @@ pub fn appendFileSystemInput(comp: *Compilation, path: Compilation.Path) Allocat...@@ -2937,27 +2988,98 @@ pub fn appendFileSystemInput(comp: *Compilation, path: Compilation.Path) Allocat
2937 fsi.appendSliceAssumeCapacity(path.sub_path);2988 fsi.appendSliceAssumeCapacity(path.sub_path);
2938}2989}
29392990
2991fn resolveEmitPath(comp: *Compilation, path: []const u8) Cache.Path {
2992 return .{
2993 .root_dir = switch (comp.cache_use) {
2994 .none => .cwd(),
2995 .incremental => |i| i.artifact_directory,
2996 .whole => |w| w.tmp_artifact_directory.?,
2997 },
2998 .sub_path = path,
2999 };
3000}
3001/// Like `resolveEmitPath`, but for calling during `flush`. The returned `Cache.Path` may reference
3002/// memory from `arena`, and may reference `path` itself.
3003/// If `kind == .temp`, then the returned path will be in a temporary or cache directory. This is
3004/// useful for intermediate files, such as the ZCU object file emitted by the LLVM backend.
3005pub fn resolveEmitPathFlush(
3006 comp: *Compilation,
3007 arena: Allocator,
3008 kind: enum { temp, artifact },
3009 path: []const u8,
3010) Allocator.Error!Cache.Path {
3011 switch (comp.cache_use) {
3012 .none => |none| return .{
3013 .root_dir = switch (kind) {
3014 .temp => none.tmp_artifact_directory.?,
3015 .artifact => .cwd(),
3016 },
3017 .sub_path = path,
3018 },
3019 .incremental, .whole => return .{
3020 .root_dir = comp.dirs.local_cache,
3021 .sub_path = try fs.path.join(arena, &.{
3022 "o",
3023 &Cache.binToHex(comp.digest.?),
3024 path,
3025 }),
3026 },
3027 }
3028}
2940fn flush(3029fn flush(
2941 comp: *Compilation,3030 comp: *Compilation,
2942 arena: Allocator,3031 arena: Allocator,
2943 default_artifact_directory: Cache.Path,
2944 tid: Zcu.PerThread.Id,3032 tid: Zcu.PerThread.Id,
2945 prog_node: std.Progress.Node,
2946) !void {3033) !void {
3034 if (comp.zcu) |zcu| {
3035 if (zcu.llvm_object) |llvm_object| {
3036 // Emit the ZCU object from LLVM now; it's required to flush the output file.
3037 // If there's an output file, it wants to decide where the LLVM object goes!
3038 const sub_prog_node = comp.link_prog_node.start("LLVM Emit Object", 0);
3039 defer sub_prog_node.end();
3040 try llvm_object.emit(.{
3041 .pre_ir_path = comp.verbose_llvm_ir,
3042 .pre_bc_path = comp.verbose_llvm_bc,
3043
3044 .bin_path = p: {
3045 const lf = comp.bin_file orelse break :p null;
3046 const p = try comp.resolveEmitPathFlush(arena, .temp, lf.zcu_object_basename.?);
3047 break :p try p.toStringZ(arena);
3048 },
3049 .asm_path = p: {
3050 const raw = comp.emit_asm orelse break :p null;
3051 const p = try comp.resolveEmitPathFlush(arena, .artifact, raw);
3052 break :p try p.toStringZ(arena);
3053 },
3054 .post_ir_path = p: {
3055 const raw = comp.emit_llvm_ir orelse break :p null;
3056 const p = try comp.resolveEmitPathFlush(arena, .artifact, raw);
3057 break :p try p.toStringZ(arena);
3058 },
3059 .post_bc_path = p: {
3060 const raw = comp.emit_llvm_bc orelse break :p null;
3061 const p = try comp.resolveEmitPathFlush(arena, .artifact, raw);
3062 break :p try p.toStringZ(arena);
3063 },
3064
3065 .is_debug = comp.root_mod.optimize_mode == .Debug,
3066 .is_small = comp.root_mod.optimize_mode == .ReleaseSmall,
3067 .time_report = comp.time_report,
3068 .sanitize_thread = comp.config.any_sanitize_thread,
3069 .fuzz = comp.config.any_fuzz,
3070 .lto = comp.config.lto,
3071 });
3072 }
3073 }
2947 if (comp.bin_file) |lf| {3074 if (comp.bin_file) |lf| {
2948 // This is needed before reading the error flags.3075 // This is needed before reading the error flags.
2949 lf.flush(arena, tid, prog_node) catch |err| switch (err) {3076 lf.flush(arena, tid, comp.link_prog_node) catch |err| switch (err) {
2950 error.LinkFailure => {}, // Already reported.3077 error.LinkFailure => {}, // Already reported.
2951 error.OutOfMemory => return error.OutOfMemory,3078 error.OutOfMemory => return error.OutOfMemory,
2952 };3079 };
2953 }3080 }
2954
2955 if (comp.zcu) |zcu| {3081 if (comp.zcu) |zcu| {
2956 try link.File.C.flushEmitH(zcu);3082 try link.File.C.flushEmitH(zcu);
2957
2958 if (zcu.llvm_object) |llvm_object| {
2959 try emitLlvmObject(comp, arena, default_artifact_directory, null, llvm_object, prog_node);
2960 }
2961 }3083 }
2962}3084}
29633085
...@@ -3009,45 +3131,6 @@ fn renameTmpIntoCache(...@@ -3009,45 +3131,6 @@ fn renameTmpIntoCache(
3009 }3131 }
3010}3132}
30113133
3012/// Communicate the output binary location to parent Compilations.
3013fn wholeCacheModeSetBinFilePath(
3014 comp: *Compilation,
3015 whole: *CacheUse.Whole,
3016 digest: *const [Cache.hex_digest_len]u8,
3017) void {
3018 const digest_start = 2; // "o/[digest]/[basename]"
3019
3020 if (whole.bin_sub_path) |sub_path| {
3021 @memcpy(sub_path[digest_start..][0..digest.len], digest);
3022 }
3023
3024 if (whole.implib_sub_path) |sub_path| {
3025 @memcpy(sub_path[digest_start..][0..digest.len], digest);
3026
3027 comp.implib_emit = .{
3028 .root_dir = comp.dirs.local_cache,
3029 .sub_path = sub_path,
3030 };
3031 }
3032
3033 if (whole.docs_sub_path) |sub_path| {
3034 @memcpy(sub_path[digest_start..][0..digest.len], digest);
3035
3036 comp.docs_emit = .{
3037 .root_dir = comp.dirs.local_cache,
3038 .sub_path = sub_path,
3039 };
3040 }
3041}
3042
3043fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemory}!?[]u8 {
3044 const emit = opt_emit orelse return null;
3045 if (emit.directory != null) return null;
3046 const s = std.fs.path.sep_str;
3047 const format = "o" ++ s ++ ("x" ** Cache.hex_digest_len) ++ s ++ "{s}";
3048 return try std.fmt.allocPrint(arena, format, .{emit.basename});
3049}
3050
3051/// This is only observed at compile-time and used to emit a compile error3134/// This is only observed at compile-time and used to emit a compile error
3052/// to remind the programmer to update multiple related pieces of code that3135/// to remind the programmer to update multiple related pieces of code that
3053/// are in different locations. Bump this number when adding or deleting3136/// are in different locations. Bump this number when adding or deleting
...@@ -3068,7 +3151,7 @@ fn addNonIncrementalStuffToCacheManifest(...@@ -3068,7 +3151,7 @@ fn addNonIncrementalStuffToCacheManifest(
3068 man.hash.addListOfBytes(comp.test_filters);3151 man.hash.addListOfBytes(comp.test_filters);
3069 man.hash.addOptionalBytes(comp.test_name_prefix);3152 man.hash.addOptionalBytes(comp.test_name_prefix);
3070 man.hash.add(comp.skip_linker_dependencies);3153 man.hash.add(comp.skip_linker_dependencies);
3071 //man.hash.add(zcu.emit_h != null);3154 //man.hash.add(zcu.emit_h != .no);
3072 man.hash.add(zcu.error_limit);3155 man.hash.add(zcu.error_limit);
3073 } else {3156 } else {
3074 cache_helpers.addModule(&man.hash, comp.root_mod);3157 cache_helpers.addModule(&man.hash, comp.root_mod);
...@@ -3114,10 +3197,6 @@ fn addNonIncrementalStuffToCacheManifest(...@@ -3114,10 +3197,6 @@ fn addNonIncrementalStuffToCacheManifest(
3114 man.hash.addListOfBytes(comp.framework_dirs);3197 man.hash.addListOfBytes(comp.framework_dirs);
3115 man.hash.addListOfBytes(comp.windows_libs.keys());3198 man.hash.addListOfBytes(comp.windows_libs.keys());
31163199
3117 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_asm);
3118 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_ir);
3119 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_bc);
3120
3121 man.hash.addListOfBytes(comp.global_cc_argv);3200 man.hash.addListOfBytes(comp.global_cc_argv);
31223201
3123 const opts = comp.cache_use.whole.lf_open_opts;3202 const opts = comp.cache_use.whole.lf_open_opts;
...@@ -3195,82 +3274,39 @@ fn addNonIncrementalStuffToCacheManifest(...@@ -3195,82 +3274,39 @@ fn addNonIncrementalStuffToCacheManifest(
3195 man.hash.addOptional(opts.minor_subsystem_version);3274 man.hash.addOptional(opts.minor_subsystem_version);
3196}3275}
31973276
3198fn emitOthers(comp: *Compilation) void {3277fn emitFromCObject(
3199 if (comp.config.output_mode != .Obj or comp.zcu != null or
3200 comp.c_object_table.count() == 0)
3201 {
3202 return;
3203 }
3204 const obj_path = comp.c_object_table.keys()[0].status.success.object_path;
3205 const ext = std.fs.path.extension(obj_path.sub_path);
3206 const dirname = obj_path.sub_path[0 .. obj_path.sub_path.len - ext.len];
3207 // This obj path always ends with the object file extension, but if we change the
3208 // extension to .ll, .bc, or .s, then it will be the path to those things.
3209 const outs = [_]struct {
3210 emit: ?EmitLoc,
3211 ext: []const u8,
3212 }{
3213 .{ .emit = comp.emit_asm, .ext = ".s" },
3214 .{ .emit = comp.emit_llvm_ir, .ext = ".ll" },
3215 .{ .emit = comp.emit_llvm_bc, .ext = ".bc" },
3216 };
3217 for (outs) |out| {
3218 if (out.emit) |loc| {
3219 if (loc.directory) |directory| {
3220 const src_path = std.fmt.allocPrint(comp.gpa, "{s}{s}", .{
3221 dirname, out.ext,
3222 }) catch |err| {
3223 log.err("unable to copy {s}{s}: {s}", .{ dirname, out.ext, @errorName(err) });
3224 continue;
3225 };
3226 defer comp.gpa.free(src_path);
3227 obj_path.root_dir.handle.copyFile(src_path, directory.handle, loc.basename, .{}) catch |err| {
3228 log.err("unable to copy {s}: {s}", .{ src_path, @errorName(err) });
3229 };
3230 }
3231 }
3232 }
3233}
3234
3235pub fn emitLlvmObject(
3236 comp: *Compilation,3278 comp: *Compilation,
3237 arena: Allocator,3279 arena: Allocator,
3238 default_artifact_directory: Cache.Path,3280 c_obj_path: Cache.Path,
3239 bin_emit_loc: ?EmitLoc,3281 new_ext: []const u8,
3240 llvm_object: LlvmObject.Ptr,3282 unresolved_emit_path: []const u8,
3241 prog_node: std.Progress.Node,3283) Allocator.Error!void {
3242) !void {3284 // The dirname and stem (i.e. everything but the extension), of the sub path of the C object.
3243 const sub_prog_node = prog_node.start("LLVM Emit Object", 0);3285 // We'll append `new_ext` to it to get the path to the right thing (asm, LLVM IR, etc).
3244 defer sub_prog_node.end();3286 const c_obj_dir_and_stem: []const u8 = p: {
32453287 const p = c_obj_path.sub_path;
3246 try llvm_object.emit(.{3288 const ext_len = fs.path.extension(p).len;
3247 .pre_ir_path = comp.verbose_llvm_ir,3289 break :p p[0 .. p.len - ext_len];
3248 .pre_bc_path = comp.verbose_llvm_bc,3290 };
3249 .bin_path = try resolveEmitLoc(arena, default_artifact_directory, bin_emit_loc),3291 const src_path: Cache.Path = .{
3250 .asm_path = try resolveEmitLoc(arena, default_artifact_directory, comp.emit_asm),3292 .root_dir = c_obj_path.root_dir,
3251 .post_ir_path = try resolveEmitLoc(arena, default_artifact_directory, comp.emit_llvm_ir),3293 .sub_path = try std.fmt.allocPrint(arena, "{s}{s}", .{
3252 .post_bc_path = try resolveEmitLoc(arena, default_artifact_directory, comp.emit_llvm_bc),3294 c_obj_dir_and_stem,
32533295 new_ext,
3254 .is_debug = comp.root_mod.optimize_mode == .Debug,3296 }),
3255 .is_small = comp.root_mod.optimize_mode == .ReleaseSmall,3297 };
3256 .time_report = comp.time_report,3298 const emit_path = comp.resolveEmitPath(unresolved_emit_path);
3257 .sanitize_thread = comp.config.any_sanitize_thread,
3258 .fuzz = comp.config.any_fuzz,
3259 .lto = comp.config.lto,
3260 });
3261}
32623299
3263fn resolveEmitLoc(3300 src_path.root_dir.handle.copyFile(
3264 arena: Allocator,3301 src_path.sub_path,
3265 default_artifact_directory: Cache.Path,3302 emit_path.root_dir.handle,
3266 opt_loc: ?EmitLoc,3303 emit_path.sub_path,
3267) Allocator.Error!?[*:0]const u8 {3304 .{},
3268 const loc = opt_loc orelse return null;3305 ) catch |err| log.err("unable to copy '{}' to '{}': {s}", .{
3269 const slice = if (loc.directory) |directory|3306 src_path,
3270 try directory.joinZ(arena, &.{loc.basename})3307 emit_path,
3271 else3308 @errorName(err),
3272 try default_artifact_directory.joinStringZ(arena, loc.basename);3309 });
3273 return slice.ptr;
3274}3310}
32753311
3276/// Having the file open for writing is problematic as far as executing the3312/// Having the file open for writing is problematic as far as executing the
...@@ -3512,7 +3548,7 @@ pub fn saveState(comp: *Compilation) !void {...@@ -3512,7 +3548,7 @@ pub fn saveState(comp: *Compilation) !void {
3512 // TODO handle the union safety field3548 // TODO handle the union safety field
3513 //addBuf(&bufs, mem.sliceAsBytes(wasm.mir_instructions.items(.data)));3549 //addBuf(&bufs, mem.sliceAsBytes(wasm.mir_instructions.items(.data)));
3514 addBuf(&bufs, mem.sliceAsBytes(wasm.mir_extra.items));3550 addBuf(&bufs, mem.sliceAsBytes(wasm.mir_extra.items));
3515 addBuf(&bufs, mem.sliceAsBytes(wasm.all_zcu_locals.items));3551 addBuf(&bufs, mem.sliceAsBytes(wasm.mir_locals.items));
3516 addBuf(&bufs, mem.sliceAsBytes(wasm.tag_name_bytes.items));3552 addBuf(&bufs, mem.sliceAsBytes(wasm.tag_name_bytes.items));
3517 addBuf(&bufs, mem.sliceAsBytes(wasm.tag_name_offs.items));3553 addBuf(&bufs, mem.sliceAsBytes(wasm.tag_name_offs.items));
35183554
...@@ -4156,28 +4192,15 @@ pub fn addWholeFileError(...@@ -4156,28 +4192,15 @@ pub fn addWholeFileError(
4156 }4192 }
4157}4193}
41584194
4159pub fn performAllTheWork(4195fn performAllTheWork(
4160 comp: *Compilation,4196 comp: *Compilation,
4161 main_progress_node: std.Progress.Node,4197 main_progress_node: std.Progress.Node,
4162) JobError!void {4198) JobError!void {
4163 comp.work_queue_progress_node = main_progress_node;4199 // Regardless of errors, `comp.zcu` needs to update its generation number.
4164 defer comp.work_queue_progress_node = .none;
4165
4166 defer if (comp.zcu) |zcu| {4200 defer if (comp.zcu) |zcu| {
4167 zcu.sema_prog_node.end();
4168 zcu.sema_prog_node = .none;
4169 zcu.codegen_prog_node.end();
4170 zcu.codegen_prog_node = .none;
4171
4172 zcu.generation += 1;4201 zcu.generation += 1;
4173 };4202 };
4174 try comp.performAllTheWorkInner(main_progress_node);
4175}
41764203
4177fn performAllTheWorkInner(
4178 comp: *Compilation,
4179 main_progress_node: std.Progress.Node,
4180) JobError!void {
4181 // Here we queue up all the AstGen tasks first, followed by C object compilation.4204 // Here we queue up all the AstGen tasks first, followed by C object compilation.
4182 // We wait until the AstGen tasks are all completed before proceeding to the4205 // We wait until the AstGen tasks are all completed before proceeding to the
4183 // (at least for now) single-threaded main work queue. However, C object compilation4206 // (at least for now) single-threaded main work queue. However, C object compilation
...@@ -4189,11 +4212,13 @@ fn performAllTheWorkInner(...@@ -4189,11 +4212,13 @@ fn performAllTheWorkInner(
4189 comp.link_task_wait_group.reset();4212 comp.link_task_wait_group.reset();
4190 defer comp.link_task_wait_group.wait();4213 defer comp.link_task_wait_group.wait();
41914214
4192 if (comp.link_task_queue.start()) {4215 comp.link_prog_node.increaseEstimatedTotalItems(
4193 comp.thread_pool.spawnWgId(&comp.link_task_wait_group, link.flushTaskQueue, .{comp});4216 comp.link_task_queue.queued_prelink.items.len + // already queued prelink tasks
4194 }4217 comp.link_task_queue.pending_prelink_tasks, // prelink tasks which will be queued
4218 );
4219 comp.link_task_queue.start(comp);
41954220
4196 if (comp.docs_emit != null) {4221 if (comp.emit_docs != null) {
4197 dev.check(.docs_emit);4222 dev.check(.docs_emit);
4198 comp.thread_pool.spawnWg(&work_queue_wait_group, workerDocsCopy, .{comp});4223 comp.thread_pool.spawnWg(&work_queue_wait_group, workerDocsCopy, .{comp});
4199 work_queue_wait_group.spawnManager(workerDocsWasm, .{ comp, main_progress_node });4224 work_queue_wait_group.spawnManager(workerDocsWasm, .{ comp, main_progress_node });
...@@ -4471,7 +4496,7 @@ fn performAllTheWorkInner(...@@ -4471,7 +4496,7 @@ fn performAllTheWorkInner(
4471 };4496 };
4472 }4497 }
4473 },4498 },
4474 .incremental => {},4499 .none, .incremental => {},
4475 }4500 }
44764501
4477 if (any_fatal_files or4502 if (any_fatal_files or
...@@ -4499,15 +4524,31 @@ fn performAllTheWorkInner(...@@ -4499,15 +4524,31 @@ fn performAllTheWorkInner(
4499 }4524 }
45004525
4501 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);4526 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
4502 zcu.codegen_prog_node = if (comp.bin_file != null) main_progress_node.start("Code Generation", 0) else .none;4527 if (comp.bin_file != null) {
4528 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
4529 }
4530 // We increment `pending_codegen_jobs` so that it doesn't reach 0 until after analysis finishes.
4531 // That prevents the "Code Generation" node from constantly disappearing and reappearing when
4532 // we're probably going to analyze more functions at some point.
4533 assert(zcu.pending_codegen_jobs.swap(1, .monotonic) == 0); // don't let this become 0 until analysis finishes
4503 }4534 }
4535 // When analysis ends, delete the progress nodes for "Semantic Analysis" and possibly "Code Generation".
4536 defer if (comp.zcu) |zcu| {
4537 zcu.sema_prog_node.end();
4538 zcu.sema_prog_node = .none;
4539 if (zcu.pending_codegen_jobs.rmw(.Sub, 1, .monotonic) == 1) {
4540 // Decremented to 0, so all done.
4541 zcu.codegen_prog_node.end();
4542 zcu.codegen_prog_node = .none;
4543 }
4544 };
45044545
4505 if (!comp.separateCodegenThreadOk()) {4546 if (!comp.separateCodegenThreadOk()) {
4506 // Waits until all input files have been parsed.4547 // Waits until all input files have been parsed.
4507 comp.link_task_wait_group.wait();4548 comp.link_task_wait_group.wait();
4508 comp.link_task_wait_group.reset();4549 comp.link_task_wait_group.reset();
4509 std.log.scoped(.link).debug("finished waiting for link_task_wait_group", .{});4550 std.log.scoped(.link).debug("finished waiting for link_task_wait_group", .{});
4510 if (comp.remaining_prelink_tasks > 0) {4551 if (comp.link_task_queue.pending_prelink_tasks > 0) {
4511 // Indicates an error occurred preventing prelink phase from completing.4552 // Indicates an error occurred preventing prelink phase from completing.
4512 return;4553 return;
4513 }4554 }
...@@ -4552,26 +4593,91 @@ pub fn queueJobs(comp: *Compilation, jobs: []const Job) !void {...@@ -4552,26 +4593,91 @@ pub fn queueJobs(comp: *Compilation, jobs: []const Job) !void {
45524593
4553fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void {4594fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void {
4554 switch (job) {4595 switch (job) {
4555 .codegen_nav => |nav_index| {4596 .codegen_func => |func| {
4597 const zcu = comp.zcu.?;
4598 const gpa = zcu.gpa;
4599 var air = func.air;
4600 errdefer {
4601 zcu.codegen_prog_node.completeOne();
4602 comp.link_prog_node.completeOne();
4603 air.deinit(gpa);
4604 }
4605 if (!air.typesFullyResolved(zcu)) {
4606 // Type resolution failed in a way which affects this function. This is a transitive
4607 // failure, but it doesn't need recording, because this function semantically depends
4608 // on the failed type, so when it is changed the function is updated.
4609 zcu.codegen_prog_node.completeOne();
4610 comp.link_prog_node.completeOne();
4611 air.deinit(gpa);
4612 return;
4613 }
4614 const shared_mir = try gpa.create(link.ZcuTask.LinkFunc.SharedMir);
4615 shared_mir.* = .{
4616 .status = .init(.pending),
4617 .value = undefined,
4618 };
4619 assert(zcu.pending_codegen_jobs.rmw(.Add, 1, .monotonic) > 0); // the "Code Generation" node hasn't been ended
4620 // This value is used as a heuristic to avoid queueing too much AIR/MIR at once (hence
4621 // using a lot of memory). If this would cause too many AIR bytes to be in-flight, we
4622 // will block on the `dispatchZcuLinkTask` call below.
4623 const air_bytes: u32 = @intCast(air.instructions.len * 5 + air.extra.items.len * 4);
4624 if (comp.separateCodegenThreadOk()) {
4625 // `workerZcuCodegen` takes ownership of `air`.
4626 comp.thread_pool.spawnWgId(&comp.link_task_wait_group, workerZcuCodegen, .{ comp, func.func, air, shared_mir });
4627 comp.dispatchZcuLinkTask(tid, .{ .link_func = .{
4628 .func = func.func,
4629 .mir = shared_mir,
4630 .air_bytes = air_bytes,
4631 } });
4632 } else {
4633 {
4634 const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid));
4635 defer pt.deactivate();
4636 pt.runCodegen(func.func, &air, shared_mir);
4637 }
4638 assert(shared_mir.status.load(.monotonic) != .pending);
4639 comp.dispatchZcuLinkTask(tid, .{ .link_func = .{
4640 .func = func.func,
4641 .mir = shared_mir,
4642 .air_bytes = air_bytes,
4643 } });
4644 air.deinit(gpa);
4645 }
4646 },
4647 .link_nav => |nav_index| {
4556 const zcu = comp.zcu.?;4648 const zcu = comp.zcu.?;
4557 const nav = zcu.intern_pool.getNav(nav_index);4649 const nav = zcu.intern_pool.getNav(nav_index);
4558 if (nav.analysis != null) {4650 if (nav.analysis != null) {
4559 const unit: InternPool.AnalUnit = .wrap(.{ .nav_val = nav_index });4651 const unit: InternPool.AnalUnit = .wrap(.{ .nav_val = nav_index });
4560 if (zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit)) {4652 if (zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit)) {
4653 comp.link_prog_node.completeOne();
4561 return;4654 return;
4562 }4655 }
4563 }4656 }
4564 assert(nav.status == .fully_resolved);4657 assert(nav.status == .fully_resolved);
4565 comp.dispatchCodegenTask(tid, .{ .codegen_nav = nav_index });4658 if (!Air.valFullyResolved(zcu.navValue(nav_index), zcu)) {
4566 },4659 // Type resolution failed in a way which affects this `Nav`. This is a transitive
4567 .codegen_func => |func| {4660 // failure, but it doesn't need recording, because this `Nav` semantically depends
4568 comp.dispatchCodegenTask(tid, .{ .codegen_func = func });4661 // on the failed type, so when it is changed the `Nav` will be updated.
4662 comp.link_prog_node.completeOne();
4663 return;
4664 }
4665 comp.dispatchZcuLinkTask(tid, .{ .link_nav = nav_index });
4569 },4666 },
4570 .codegen_type => |ty| {4667 .link_type => |ty| {
4571 comp.dispatchCodegenTask(tid, .{ .codegen_type = ty });4668 const zcu = comp.zcu.?;
4669 if (zcu.failed_types.fetchSwapRemove(ty)) |*entry| entry.value.deinit(zcu.gpa);
4670 if (!Air.typeFullyResolved(.fromInterned(ty), zcu)) {
4671 // Type resolution failed in a way which affects this type. This is a transitive
4672 // failure, but it doesn't need recording, because this type semantically depends
4673 // on the failed type, so when that is changed, this type will be updated.
4674 comp.link_prog_node.completeOne();
4675 return;
4676 }
4677 comp.dispatchZcuLinkTask(tid, .{ .link_type = ty });
4572 },4678 },
4573 .update_line_number => |ti| {4679 .update_line_number => |ti| {
4574 comp.dispatchCodegenTask(tid, .{ .update_line_number = ti });4680 comp.dispatchZcuLinkTask(tid, .{ .update_line_number = ti });
4575 },4681 },
4576 .analyze_func => |func| {4682 .analyze_func => |func| {
4577 const named_frame = tracy.namedFrame("analyze_func");4683 const named_frame = tracy.namedFrame("analyze_func");
...@@ -4663,18 +4769,7 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void {...@@ -4663,18 +4769,7 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void {
4663 }4769 }
4664}4770}
46654771
4666/// The reason for the double-queue here is that the first queue ensures any4772pub fn separateCodegenThreadOk(comp: *const Compilation) bool {
4667/// resolve_type_fully tasks are complete before this dispatch function is called.
4668fn dispatchCodegenTask(comp: *Compilation, tid: usize, link_task: link.Task) void {
4669 if (comp.separateCodegenThreadOk()) {
4670 comp.queueLinkTasks(&.{link_task});
4671 } else {
4672 assert(comp.remaining_prelink_tasks == 0);
4673 link.doTask(comp, tid, link_task);
4674 }
4675}
4676
4677fn separateCodegenThreadOk(comp: *const Compilation) bool {
4678 if (InternPool.single_threaded) return false;4773 if (InternPool.single_threaded) return false;
4679 const zcu = comp.zcu orelse return true;4774 const zcu = comp.zcu orelse return true;
4680 return zcu.backendSupportsFeature(.separate_thread);4775 return zcu.backendSupportsFeature(.separate_thread);
...@@ -4694,12 +4789,12 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void {...@@ -4694,12 +4789,12 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void {
4694 const zcu = comp.zcu orelse4789 const zcu = comp.zcu orelse
4695 return comp.lockAndSetMiscFailure(.docs_copy, "no Zig code to document", .{});4790 return comp.lockAndSetMiscFailure(.docs_copy, "no Zig code to document", .{});
46964791
4697 const emit = comp.docs_emit.?;4792 const docs_path = comp.resolveEmitPath(comp.emit_docs.?);
4698 var out_dir = emit.root_dir.handle.makeOpenPath(emit.sub_path, .{}) catch |err| {4793 var out_dir = docs_path.root_dir.handle.makeOpenPath(docs_path.sub_path, .{}) catch |err| {
4699 return comp.lockAndSetMiscFailure(4794 return comp.lockAndSetMiscFailure(
4700 .docs_copy,4795 .docs_copy,
4701 "unable to create output directory '{}{s}': {s}",4796 "unable to create output directory '{}': {s}",
4702 .{ emit.root_dir, emit.sub_path, @errorName(err) },4797 .{ docs_path, @errorName(err) },
4703 );4798 );
4704 };4799 };
4705 defer out_dir.close();4800 defer out_dir.close();
...@@ -4718,8 +4813,8 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void {...@@ -4718,8 +4813,8 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void {
4718 var tar_file = out_dir.createFile("sources.tar", .{}) catch |err| {4813 var tar_file = out_dir.createFile("sources.tar", .{}) catch |err| {
4719 return comp.lockAndSetMiscFailure(4814 return comp.lockAndSetMiscFailure(
4720 .docs_copy,4815 .docs_copy,
4721 "unable to create '{}{s}/sources.tar': {s}",4816 "unable to create '{}/sources.tar': {s}",
4722 .{ emit.root_dir, emit.sub_path, @errorName(err) },4817 .{ docs_path, @errorName(err) },
4723 );4818 );
4724 };4819 };
4725 defer tar_file.close();4820 defer tar_file.close();
...@@ -4869,11 +4964,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -4869,11 +4964,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
4869 .parent = root_mod,4964 .parent = root_mod,
4870 });4965 });
4871 try root_mod.deps.put(arena, "Walk", walk_mod);4966 try root_mod.deps.put(arena, "Walk", walk_mod);
4872 const bin_basename = try std.zig.binNameAlloc(arena, .{
4873 .root_name = root_name,
4874 .target = resolved_target.result,
4875 .output_mode = output_mode,
4876 });
48774967
4878 const sub_compilation = try Compilation.create(gpa, arena, .{4968 const sub_compilation = try Compilation.create(gpa, arena, .{
4879 .dirs = dirs,4969 .dirs = dirs,
...@@ -4885,10 +4975,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -4885,10 +4975,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
4885 .root_name = root_name,4975 .root_name = root_name,
4886 .thread_pool = comp.thread_pool,4976 .thread_pool = comp.thread_pool,
4887 .libc_installation = comp.libc_installation,4977 .libc_installation = comp.libc_installation,
4888 .emit_bin = .{4978 .emit_bin = .yes_cache,
4889 .directory = null, // Put it in the cache directory.
4890 .basename = bin_basename,
4891 },
4892 .verbose_cc = comp.verbose_cc,4979 .verbose_cc = comp.verbose_cc,
4893 .verbose_link = comp.verbose_link,4980 .verbose_link = comp.verbose_link,
4894 .verbose_air = comp.verbose_air,4981 .verbose_air = comp.verbose_air,
...@@ -4903,27 +4990,31 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -4903,27 +4990,31 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
49034990
4904 try comp.updateSubCompilation(sub_compilation, .docs_wasm, prog_node);4991 try comp.updateSubCompilation(sub_compilation, .docs_wasm, prog_node);
49054992
4906 const emit = comp.docs_emit.?;4993 var crt_file = try sub_compilation.toCrtFile();
4907 var out_dir = emit.root_dir.handle.makeOpenPath(emit.sub_path, .{}) catch |err| {4994 defer crt_file.deinit(gpa);
4995
4996 const docs_bin_file = crt_file.full_object_path;
4997 assert(docs_bin_file.sub_path.len > 0); // emitted binary is not a directory
4998
4999 const docs_path = comp.resolveEmitPath(comp.emit_docs.?);
5000 var out_dir = docs_path.root_dir.handle.makeOpenPath(docs_path.sub_path, .{}) catch |err| {
4908 return comp.lockAndSetMiscFailure(5001 return comp.lockAndSetMiscFailure(
4909 .docs_copy,5002 .docs_copy,
4910 "unable to create output directory '{}{s}': {s}",5003 "unable to create output directory '{}': {s}",
4911 .{ emit.root_dir, emit.sub_path, @errorName(err) },5004 .{ docs_path, @errorName(err) },
4912 );5005 );
4913 };5006 };
4914 defer out_dir.close();5007 defer out_dir.close();
49155008
4916 sub_compilation.dirs.local_cache.handle.copyFile(5009 crt_file.full_object_path.root_dir.handle.copyFile(
4917 sub_compilation.cache_use.whole.bin_sub_path.?,5010 crt_file.full_object_path.sub_path,
4918 out_dir,5011 out_dir,
4919 "main.wasm",5012 "main.wasm",
4920 .{},5013 .{},
4921 ) catch |err| {5014 ) catch |err| {
4922 return comp.lockAndSetMiscFailure(.docs_copy, "unable to copy '{}{s}' to '{}{s}': {s}", .{5015 return comp.lockAndSetMiscFailure(.docs_copy, "unable to copy '{}' to '{}': {s}", .{
4923 sub_compilation.dirs.local_cache,5016 crt_file.full_object_path,
4924 sub_compilation.cache_use.whole.bin_sub_path.?,5017 docs_path,
4925 emit.root_dir,
4926 emit.sub_path,
4927 @errorName(err),5018 @errorName(err),
4928 });5019 });
4929 };5020 };
...@@ -5185,7 +5276,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module...@@ -5185,7 +5276,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module
5185 defer whole.cache_manifest_mutex.unlock();5276 defer whole.cache_manifest_mutex.unlock();
5186 try whole_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);5277 try whole_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);
5187 },5278 },
5188 .incremental => {},5279 .incremental, .none => {},
5189 }5280 }
51905281
5191 const bin_digest = man.finalBin();5282 const bin_digest = man.finalBin();
...@@ -5261,6 +5352,21 @@ pub const RtOptions = struct {...@@ -5261,6 +5352,21 @@ pub const RtOptions = struct {
5261 allow_lto: bool = true,5352 allow_lto: bool = true,
5262};5353};
52635354
5355fn workerZcuCodegen(
5356 tid: usize,
5357 comp: *Compilation,
5358 func_index: InternPool.Index,
5359 orig_air: Air,
5360 out: *link.ZcuTask.LinkFunc.SharedMir,
5361) void {
5362 var air = orig_air;
5363 // We own `air` now, so we are responsbile for freeing it.
5364 defer air.deinit(comp.gpa);
5365 const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid));
5366 defer pt.deactivate();
5367 pt.runCodegen(func_index, &air, out);
5368}
5369
5264fn buildRt(5370fn buildRt(
5265 comp: *Compilation,5371 comp: *Compilation,
5266 root_source_name: []const u8,5372 root_source_name: []const u8,
...@@ -5515,9 +5621,9 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr...@@ -5515,9 +5621,9 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
5515 defer man.deinit();5621 defer man.deinit();
55165622
5517 man.hash.add(comp.clang_preprocessor_mode);5623 man.hash.add(comp.clang_preprocessor_mode);
5518 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_asm);5624 man.hash.addOptionalBytes(comp.emit_asm);
5519 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_ir);5625 man.hash.addOptionalBytes(comp.emit_llvm_ir);
5520 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_bc);5626 man.hash.addOptionalBytes(comp.emit_llvm_bc);
55215627
5522 try cache_helpers.hashCSource(&man, c_object.src);5628 try cache_helpers.hashCSource(&man, c_object.src);
55235629
...@@ -5751,7 +5857,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr...@@ -5751,7 +5857,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
5751 try whole_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);5857 try whole_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);
5752 }5858 }
5753 },5859 },
5754 .incremental => {},5860 .incremental, .none => {},
5755 }5861 }
5756 }5862 }
57575863
...@@ -5792,7 +5898,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr...@@ -5792,7 +5898,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
5792 },5898 },
5793 };5899 };
57945900
5795 comp.queueLinkTasks(&.{.{ .load_object = c_object.status.success.object_path }});5901 comp.queuePrelinkTasks(&.{.{ .load_object = c_object.status.success.object_path }});
5796}5902}
57975903
5798fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32_resource_prog_node: std.Progress.Node) !void {5904fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32_resource_prog_node: std.Progress.Node) !void {
...@@ -5995,7 +6101,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32...@@ -5995,7 +6101,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
5995 defer whole.cache_manifest_mutex.unlock();6101 defer whole.cache_manifest_mutex.unlock();
5996 try whole_cache_manifest.addFilePost(dep_file_path);6102 try whole_cache_manifest.addFilePost(dep_file_path);
5997 },6103 },
5998 .incremental => {},6104 .incremental, .none => {},
5999 }6105 }
6000 }6106 }
6001 }6107 }
...@@ -7167,12 +7273,6 @@ fn buildOutputFromZig(...@@ -7167,12 +7273,6 @@ fn buildOutputFromZig(
7167 .cc_argv = &.{},7273 .cc_argv = &.{},
7168 .parent = null,7274 .parent = null,
7169 });7275 });
7170 const target = comp.getTarget();
7171 const bin_basename = try std.zig.binNameAlloc(arena, .{
7172 .root_name = root_name,
7173 .target = target,
7174 .output_mode = output_mode,
7175 });
71767276
7177 const parent_whole_cache: ?ParentWholeCache = switch (comp.cache_use) {7277 const parent_whole_cache: ?ParentWholeCache = switch (comp.cache_use) {
7178 .whole => |whole| .{7278 .whole => |whole| .{
...@@ -7185,7 +7285,7 @@ fn buildOutputFromZig(...@@ -7185,7 +7285,7 @@ fn buildOutputFromZig(
7185 3, // global cache is the same7285 3, // global cache is the same
7186 },7286 },
7187 },7287 },
7188 .incremental => null,7288 .incremental, .none => null,
7189 };7289 };
71907290
7191 const sub_compilation = try Compilation.create(gpa, arena, .{7291 const sub_compilation = try Compilation.create(gpa, arena, .{
...@@ -7198,13 +7298,9 @@ fn buildOutputFromZig(...@@ -7198,13 +7298,9 @@ fn buildOutputFromZig(
7198 .root_name = root_name,7298 .root_name = root_name,
7199 .thread_pool = comp.thread_pool,7299 .thread_pool = comp.thread_pool,
7200 .libc_installation = comp.libc_installation,7300 .libc_installation = comp.libc_installation,
7201 .emit_bin = .{7301 .emit_bin = .yes_cache,
7202 .directory = null, // Put it in the cache directory.
7203 .basename = bin_basename,
7204 },
7205 .function_sections = true,7302 .function_sections = true,
7206 .data_sections = true,7303 .data_sections = true,
7207 .emit_h = null,
7208 .verbose_cc = comp.verbose_cc,7304 .verbose_cc = comp.verbose_cc,
7209 .verbose_link = comp.verbose_link,7305 .verbose_link = comp.verbose_link,
7210 .verbose_air = comp.verbose_air,7306 .verbose_air = comp.verbose_air,
...@@ -7225,7 +7321,7 @@ fn buildOutputFromZig(...@@ -7225,7 +7321,7 @@ fn buildOutputFromZig(
7225 assert(out.* == null);7321 assert(out.* == null);
7226 out.* = crt_file;7322 out.* = crt_file;
72277323
7228 comp.queueLinkTaskMode(crt_file.full_object_path, &config);7324 comp.queuePrelinkTaskMode(crt_file.full_object_path, &config);
7229}7325}
72307326
7231pub const CrtFileOptions = struct {7327pub const CrtFileOptions = struct {
...@@ -7324,13 +7420,9 @@ pub fn build_crt_file(...@@ -7324,13 +7420,9 @@ pub fn build_crt_file(
7324 .root_name = root_name,7420 .root_name = root_name,
7325 .thread_pool = comp.thread_pool,7421 .thread_pool = comp.thread_pool,
7326 .libc_installation = comp.libc_installation,7422 .libc_installation = comp.libc_installation,
7327 .emit_bin = .{7423 .emit_bin = .yes_cache,
7328 .directory = null, // Put it in the cache directory.
7329 .basename = basename,
7330 },
7331 .function_sections = options.function_sections orelse false,7424 .function_sections = options.function_sections orelse false,
7332 .data_sections = options.data_sections orelse false,7425 .data_sections = options.data_sections orelse false,
7333 .emit_h = null,
7334 .c_source_files = c_source_files,7426 .c_source_files = c_source_files,
7335 .verbose_cc = comp.verbose_cc,7427 .verbose_cc = comp.verbose_cc,
7336 .verbose_link = comp.verbose_link,7428 .verbose_link = comp.verbose_link,
...@@ -7349,7 +7441,7 @@ pub fn build_crt_file(...@@ -7349,7 +7441,7 @@ pub fn build_crt_file(
7349 try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);7441 try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);
73507442
7351 const crt_file = try sub_compilation.toCrtFile();7443 const crt_file = try sub_compilation.toCrtFile();
7352 comp.queueLinkTaskMode(crt_file.full_object_path, &config);7444 comp.queuePrelinkTaskMode(crt_file.full_object_path, &config);
73537445
7354 {7446 {
7355 comp.mutex.lock();7447 comp.mutex.lock();
...@@ -7359,8 +7451,8 @@ pub fn build_crt_file(...@@ -7359,8 +7451,8 @@ pub fn build_crt_file(
7359 }7451 }
7360}7452}
73617453
7362pub fn queueLinkTaskMode(comp: *Compilation, path: Cache.Path, config: *const Compilation.Config) void {7454pub fn queuePrelinkTaskMode(comp: *Compilation, path: Cache.Path, config: *const Compilation.Config) void {
7363 comp.queueLinkTasks(switch (config.output_mode) {7455 comp.queuePrelinkTasks(switch (config.output_mode) {
7364 .Exe => unreachable,7456 .Exe => unreachable,
7365 .Obj => &.{.{ .load_object = path }},7457 .Obj => &.{.{ .load_object = path }},
7366 .Lib => &.{switch (config.link_mode) {7458 .Lib => &.{switch (config.link_mode) {
...@@ -7372,19 +7464,41 @@ pub fn queueLinkTaskMode(comp: *Compilation, path: Cache.Path, config: *const Co...@@ -7372,19 +7464,41 @@ pub fn queueLinkTaskMode(comp: *Compilation, path: Cache.Path, config: *const Co
73727464
7373/// Only valid to call during `update`. Automatically handles queuing up a7465/// Only valid to call during `update`. Automatically handles queuing up a
7374/// linker worker task if there is not already one.7466/// linker worker task if there is not already one.
7375pub fn queueLinkTasks(comp: *Compilation, tasks: []const link.Task) void {7467pub fn queuePrelinkTasks(comp: *Compilation, tasks: []const link.PrelinkTask) void {
7376 if (comp.link_task_queue.enqueue(comp.gpa, tasks) catch |err| switch (err) {7468 comp.link_task_queue.enqueuePrelink(comp, tasks) catch |err| switch (err) {
7377 error.OutOfMemory => return comp.setAllocFailure(),7469 error.OutOfMemory => return comp.setAllocFailure(),
7378 }) {7470 };
7379 comp.thread_pool.spawnWgId(&comp.link_task_wait_group, link.flushTaskQueue, .{comp});7471}
7472
7473/// The reason for the double-queue here is that the first queue ensures any
7474/// resolve_type_fully tasks are complete before this dispatch function is called.
7475fn dispatchZcuLinkTask(comp: *Compilation, tid: usize, task: link.ZcuTask) void {
7476 if (!comp.separateCodegenThreadOk()) {
7477 assert(tid == 0);
7478 if (task == .link_func) {
7479 assert(task.link_func.mir.status.load(.monotonic) != .pending);
7480 }
7481 link.doZcuTask(comp, tid, task);
7482 task.deinit(comp.zcu.?);
7483 return;
7380 }7484 }
7485 comp.link_task_queue.enqueueZcu(comp, task) catch |err| switch (err) {
7486 error.OutOfMemory => {
7487 task.deinit(comp.zcu.?);
7488 comp.setAllocFailure();
7489 },
7490 };
7381}7491}
73827492
7383pub fn toCrtFile(comp: *Compilation) Allocator.Error!CrtFile {7493pub fn toCrtFile(comp: *Compilation) Allocator.Error!CrtFile {
7384 return .{7494 return .{
7385 .full_object_path = .{7495 .full_object_path = .{
7386 .root_dir = comp.dirs.local_cache,7496 .root_dir = comp.dirs.local_cache,
7387 .sub_path = try comp.gpa.dupe(u8, comp.cache_use.whole.bin_sub_path.?),7497 .sub_path = try std.fs.path.join(comp.gpa, &.{
7498 "o",
7499 &Cache.binToHex(comp.digest.?),
7500 comp.emit_bin.?,
7501 }),
7388 },7502 },
7389 .lock = comp.cache_use.whole.moveLock(),7503 .lock = comp.cache_use.whole.moveLock(),
7390 };7504 };
src/InternPool.zig+51
...@@ -3249,6 +3249,9 @@ pub const LoadedUnionType = struct {...@@ -3249,6 +3249,9 @@ pub const LoadedUnionType = struct {
3249 name: NullTerminatedString,3249 name: NullTerminatedString,
3250 /// Represents the declarations inside this union.3250 /// Represents the declarations inside this union.
3251 namespace: NamespaceIndex,3251 namespace: NamespaceIndex,
3252 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.
3253 /// Otherwise, this is `.none`.
3254 name_nav: Nav.Index.Optional,
3252 /// The enum tag type.3255 /// The enum tag type.
3253 enum_tag_ty: Index,3256 enum_tag_ty: Index,
3254 /// List of field types in declaration order.3257 /// List of field types in declaration order.
...@@ -3567,6 +3570,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {...@@ -3567,6 +3570,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
3567 .tid = unwrapped_index.tid,3570 .tid = unwrapped_index.tid,
3568 .extra_index = data,3571 .extra_index = data,
3569 .name = type_union.data.name,3572 .name = type_union.data.name,
3573 .name_nav = type_union.data.name_nav,
3570 .namespace = type_union.data.namespace,3574 .namespace = type_union.data.namespace,
3571 .enum_tag_ty = type_union.data.tag_ty,3575 .enum_tag_ty = type_union.data.tag_ty,
3572 .field_types = field_types,3576 .field_types = field_types,
...@@ -3584,6 +3588,9 @@ pub const LoadedStructType = struct {...@@ -3584,6 +3588,9 @@ pub const LoadedStructType = struct {
3584 /// The name of this struct type.3588 /// The name of this struct type.
3585 name: NullTerminatedString,3589 name: NullTerminatedString,
3586 namespace: NamespaceIndex,3590 namespace: NamespaceIndex,
3591 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.
3592 /// Otherwise, or if this is a file's root struct type, this is `.none`.
3593 name_nav: Nav.Index.Optional,
3587 /// Index of the `struct_decl` or `reify` ZIR instruction.3594 /// Index of the `struct_decl` or `reify` ZIR instruction.
3588 zir_index: TrackedInst.Index,3595 zir_index: TrackedInst.Index,
3589 layout: std.builtin.Type.ContainerLayout,3596 layout: std.builtin.Type.ContainerLayout,
...@@ -4173,6 +4180,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -4173,6 +4180,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
4173 switch (item.tag) {4180 switch (item.tag) {
4174 .type_struct => {4181 .type_struct => {
4175 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "name").?]);4182 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "name").?]);
4183 const name_nav: Nav.Index.Optional = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "name_nav").?]);
4176 const namespace: NamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?]);4184 const namespace: NamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?]);
4177 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);4185 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);
4178 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?];4186 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?];
...@@ -4259,6 +4267,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -4259,6 +4267,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
4259 .tid = unwrapped_index.tid,4267 .tid = unwrapped_index.tid,
4260 .extra_index = item.data,4268 .extra_index = item.data,
4261 .name = name,4269 .name = name,
4270 .name_nav = name_nav,
4262 .namespace = namespace,4271 .namespace = namespace,
4263 .zir_index = zir_index,4272 .zir_index = zir_index,
4264 .layout = if (flags.is_extern) .@"extern" else .auto,4273 .layout = if (flags.is_extern) .@"extern" else .auto,
...@@ -4275,6 +4284,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -4275,6 +4284,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
4275 },4284 },
4276 .type_struct_packed, .type_struct_packed_inits => {4285 .type_struct_packed, .type_struct_packed_inits => {
4277 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?]);4286 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?]);
4287 const name_nav: Nav.Index.Optional = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "name_nav").?]);
4278 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);4288 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);
4279 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "fields_len").?];4289 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "fields_len").?];
4280 const namespace: NamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]);4290 const namespace: NamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]);
...@@ -4321,6 +4331,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -4321,6 +4331,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
4321 .tid = unwrapped_index.tid,4331 .tid = unwrapped_index.tid,
4322 .extra_index = item.data,4332 .extra_index = item.data,
4323 .name = name,4333 .name = name,
4334 .name_nav = name_nav,
4324 .namespace = namespace,4335 .namespace = namespace,
4325 .zir_index = zir_index,4336 .zir_index = zir_index,
4326 .layout = .@"packed",4337 .layout = .@"packed",
...@@ -4345,6 +4356,9 @@ pub const LoadedEnumType = struct {...@@ -4345,6 +4356,9 @@ pub const LoadedEnumType = struct {
4345 name: NullTerminatedString,4356 name: NullTerminatedString,
4346 /// Represents the declarations inside this enum.4357 /// Represents the declarations inside this enum.
4347 namespace: NamespaceIndex,4358 namespace: NamespaceIndex,
4359 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.
4360 /// Otherwise, this is `.none`.
4361 name_nav: Nav.Index.Optional,
4348 /// An integer type which is used for the numerical value of the enum.4362 /// An integer type which is used for the numerical value of the enum.
4349 /// This field is present regardless of whether the enum has an4363 /// This field is present regardless of whether the enum has an
4350 /// explicitly provided tag type or auto-numbered.4364 /// explicitly provided tag type or auto-numbered.
...@@ -4428,6 +4442,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -4428,6 +4442,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
4428 } else extra.data.captures_len;4442 } else extra.data.captures_len;
4429 return .{4443 return .{
4430 .name = extra.data.name,4444 .name = extra.data.name,
4445 .name_nav = extra.data.name_nav,
4431 .namespace = extra.data.namespace,4446 .namespace = extra.data.namespace,
4432 .tag_ty = extra.data.int_tag_type,4447 .tag_ty = extra.data.int_tag_type,
4433 .names = .{4448 .names = .{
...@@ -4462,6 +4477,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -4462,6 +4477,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
4462 } else extra.data.captures_len;4477 } else extra.data.captures_len;
4463 return .{4478 return .{
4464 .name = extra.data.name,4479 .name = extra.data.name,
4480 .name_nav = extra.data.name_nav,
4465 .namespace = extra.data.namespace,4481 .namespace = extra.data.namespace,
4466 .tag_ty = extra.data.int_tag_type,4482 .tag_ty = extra.data.int_tag_type,
4467 .names = .{4483 .names = .{
...@@ -4493,6 +4509,9 @@ pub const LoadedOpaqueType = struct {...@@ -4493,6 +4509,9 @@ pub const LoadedOpaqueType = struct {
4493 // TODO: the non-fqn will be needed by the new dwarf structure4509 // TODO: the non-fqn will be needed by the new dwarf structure
4494 /// The name of this opaque type.4510 /// The name of this opaque type.
4495 name: NullTerminatedString,4511 name: NullTerminatedString,
4512 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.
4513 /// Otherwise, this is `.none`.
4514 name_nav: Nav.Index.Optional,
4496 /// Index of the `opaque_decl` or `reify` instruction.4515 /// Index of the `opaque_decl` or `reify` instruction.
4497 zir_index: TrackedInst.Index,4516 zir_index: TrackedInst.Index,
4498 captures: CaptureValue.Slice,4517 captures: CaptureValue.Slice,
...@@ -4509,6 +4528,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {...@@ -4509,6 +4528,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
4509 extra.data.captures_len;4528 extra.data.captures_len;
4510 return .{4529 return .{
4511 .name = extra.data.name,4530 .name = extra.data.name,
4531 .name_nav = extra.data.name_nav,
4512 .namespace = extra.data.namespace,4532 .namespace = extra.data.namespace,
4513 .zir_index = extra.data.zir_index,4533 .zir_index = extra.data.zir_index,
4514 .captures = .{4534 .captures = .{
...@@ -6022,6 +6042,7 @@ pub const Tag = enum(u8) {...@@ -6022,6 +6042,7 @@ pub const Tag = enum(u8) {
6022 /// 4. field align: Alignment for each field; declaration order6042 /// 4. field align: Alignment for each field; declaration order
6023 pub const TypeUnion = struct {6043 pub const TypeUnion = struct {
6024 name: NullTerminatedString,6044 name: NullTerminatedString,
6045 name_nav: Nav.Index.Optional,
6025 flags: Flags,6046 flags: Flags,
6026 /// This could be provided through the tag type, but it is more convenient6047 /// This could be provided through the tag type, but it is more convenient
6027 /// to store it directly. This is also necessary for `dumpStatsFallible` to6048 /// to store it directly. This is also necessary for `dumpStatsFallible` to
...@@ -6061,6 +6082,7 @@ pub const Tag = enum(u8) {...@@ -6061,6 +6082,7 @@ pub const Tag = enum(u8) {
6061 /// 5. init: Index for each fields_len // if tag is type_struct_packed_inits6082 /// 5. init: Index for each fields_len // if tag is type_struct_packed_inits
6062 pub const TypeStructPacked = struct {6083 pub const TypeStructPacked = struct {
6063 name: NullTerminatedString,6084 name: NullTerminatedString,
6085 name_nav: Nav.Index.Optional,
6064 zir_index: TrackedInst.Index,6086 zir_index: TrackedInst.Index,
6065 fields_len: u32,6087 fields_len: u32,
6066 namespace: NamespaceIndex,6088 namespace: NamespaceIndex,
...@@ -6108,6 +6130,7 @@ pub const Tag = enum(u8) {...@@ -6108,6 +6130,7 @@ pub const Tag = enum(u8) {
6108 /// 8. field_offset: u32 // for each field in declared order, undef until layout_resolved6130 /// 8. field_offset: u32 // for each field in declared order, undef until layout_resolved
6109 pub const TypeStruct = struct {6131 pub const TypeStruct = struct {
6110 name: NullTerminatedString,6132 name: NullTerminatedString,
6133 name_nav: Nav.Index.Optional,
6111 zir_index: TrackedInst.Index,6134 zir_index: TrackedInst.Index,
6112 namespace: NamespaceIndex,6135 namespace: NamespaceIndex,
6113 fields_len: u32,6136 fields_len: u32,
...@@ -6151,6 +6174,7 @@ pub const Tag = enum(u8) {...@@ -6151,6 +6174,7 @@ pub const Tag = enum(u8) {
6151 /// 0. capture: CaptureValue // for each `captures_len`6174 /// 0. capture: CaptureValue // for each `captures_len`
6152 pub const TypeOpaque = struct {6175 pub const TypeOpaque = struct {
6153 name: NullTerminatedString,6176 name: NullTerminatedString,
6177 name_nav: Nav.Index.Optional,
6154 /// Contains the declarations inside this opaque.6178 /// Contains the declarations inside this opaque.
6155 namespace: NamespaceIndex,6179 namespace: NamespaceIndex,
6156 /// The index of the `opaque_decl` instruction.6180 /// The index of the `opaque_decl` instruction.
...@@ -6429,6 +6453,7 @@ pub const Array = struct {...@@ -6429,6 +6453,7 @@ pub const Array = struct {
6429/// 4. tag value: Index for each fields_len; declaration order6453/// 4. tag value: Index for each fields_len; declaration order
6430pub const EnumExplicit = struct {6454pub const EnumExplicit = struct {
6431 name: NullTerminatedString,6455 name: NullTerminatedString,
6456 name_nav: Nav.Index.Optional,
6432 /// `std.math.maxInt(u32)` indicates this type is reified.6457 /// `std.math.maxInt(u32)` indicates this type is reified.
6433 captures_len: u32,6458 captures_len: u32,
6434 namespace: NamespaceIndex,6459 namespace: NamespaceIndex,
...@@ -6454,6 +6479,7 @@ pub const EnumExplicit = struct {...@@ -6454,6 +6479,7 @@ pub const EnumExplicit = struct {
6454/// 3. field name: NullTerminatedString for each fields_len; declaration order6479/// 3. field name: NullTerminatedString for each fields_len; declaration order
6455pub const EnumAuto = struct {6480pub const EnumAuto = struct {
6456 name: NullTerminatedString,6481 name: NullTerminatedString,
6482 name_nav: Nav.Index.Optional,
6457 /// `std.math.maxInt(u32)` indicates this type is reified.6483 /// `std.math.maxInt(u32)` indicates this type is reified.
6458 captures_len: u32,6484 captures_len: u32,
6459 namespace: NamespaceIndex,6485 namespace: NamespaceIndex,
...@@ -8666,6 +8692,7 @@ pub fn getUnionType(...@@ -8666,6 +8692,7 @@ pub fn getUnionType(
8666 .size = std.math.maxInt(u32),8692 .size = std.math.maxInt(u32),
8667 .padding = std.math.maxInt(u32),8693 .padding = std.math.maxInt(u32),
8668 .name = undefined, // set by `finish`8694 .name = undefined, // set by `finish`
8695 .name_nav = undefined, // set by `finish`
8669 .namespace = undefined, // set by `finish`8696 .namespace = undefined, // set by `finish`
8670 .tag_ty = ini.enum_tag_ty,8697 .tag_ty = ini.enum_tag_ty,
8671 .zir_index = switch (ini.key) {8698 .zir_index = switch (ini.key) {
...@@ -8717,6 +8744,7 @@ pub fn getUnionType(...@@ -8717,6 +8744,7 @@ pub fn getUnionType(
8717 .tid = tid,8744 .tid = tid,
8718 .index = gop.put(),8745 .index = gop.put(),
8719 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name").?,8746 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name").?,
8747 .name_nav_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name_nav").?,
8720 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?,8748 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?,
8721 } };8749 } };
8722}8750}
...@@ -8726,15 +8754,20 @@ pub const WipNamespaceType = struct {...@@ -8726,15 +8754,20 @@ pub const WipNamespaceType = struct {
8726 index: Index,8754 index: Index,
8727 type_name_extra_index: u32,8755 type_name_extra_index: u32,
8728 namespace_extra_index: u32,8756 namespace_extra_index: u32,
8757 name_nav_extra_index: u32,
87298758
8730 pub fn setName(8759 pub fn setName(
8731 wip: WipNamespaceType,8760 wip: WipNamespaceType,
8732 ip: *InternPool,8761 ip: *InternPool,
8733 type_name: NullTerminatedString,8762 type_name: NullTerminatedString,
8763 /// This should be the `Nav` we are named after if we use the `.parent` name strategy; `.none` otherwise.
8764 /// This is also `.none` if we use `.parent` because we are the root struct type for a file.
8765 name_nav: Nav.Index.Optional,
8734 ) void {8766 ) void {
8735 const extra = ip.getLocalShared(wip.tid).extra.acquire();8767 const extra = ip.getLocalShared(wip.tid).extra.acquire();
8736 const extra_items = extra.view().items(.@"0");8768 const extra_items = extra.view().items(.@"0");
8737 extra_items[wip.type_name_extra_index] = @intFromEnum(type_name);8769 extra_items[wip.type_name_extra_index] = @intFromEnum(type_name);
8770 extra_items[wip.name_nav_extra_index] = @intFromEnum(name_nav);
8738 }8771 }
87398772
8740 pub fn finish(8773 pub fn finish(
...@@ -8843,6 +8876,7 @@ pub fn getStructType(...@@ -8843,6 +8876,7 @@ pub fn getStructType(
8843 ini.fields_len); // inits8876 ini.fields_len); // inits
8844 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{8877 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
8845 .name = undefined, // set by `finish`8878 .name = undefined, // set by `finish`
8879 .name_nav = undefined, // set by `finish`
8846 .zir_index = zir_index,8880 .zir_index = zir_index,
8847 .fields_len = ini.fields_len,8881 .fields_len = ini.fields_len,
8848 .namespace = undefined, // set by `finish`8882 .namespace = undefined, // set by `finish`
...@@ -8887,6 +8921,7 @@ pub fn getStructType(...@@ -8887,6 +8921,7 @@ pub fn getStructType(
8887 .tid = tid,8921 .tid = tid,
8888 .index = gop.put(),8922 .index = gop.put(),
8889 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?,8923 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?,
8924 .name_nav_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name_nav").?,
8890 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?,8925 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?,
8891 } };8926 } };
8892 },8927 },
...@@ -8909,6 +8944,7 @@ pub fn getStructType(...@@ -8909,6 +8944,7 @@ pub fn getStructType(
8909 1); // names_map8944 1); // names_map
8910 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{8945 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{
8911 .name = undefined, // set by `finish`8946 .name = undefined, // set by `finish`
8947 .name_nav = undefined, // set by `finish`
8912 .zir_index = zir_index,8948 .zir_index = zir_index,
8913 .namespace = undefined, // set by `finish`8949 .namespace = undefined, // set by `finish`
8914 .fields_len = ini.fields_len,8950 .fields_len = ini.fields_len,
...@@ -8977,6 +9013,7 @@ pub fn getStructType(...@@ -8977,6 +9013,7 @@ pub fn getStructType(
8977 .tid = tid,9013 .tid = tid,
8978 .index = gop.put(),9014 .index = gop.put(),
8979 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name").?,9015 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name").?,
9016 .name_nav_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name_nav").?,
8980 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?,9017 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?,
8981 } };9018 } };
8982}9019}
...@@ -9766,6 +9803,7 @@ pub const WipEnumType = struct {...@@ -9766,6 +9803,7 @@ pub const WipEnumType = struct {
9766 tag_ty_index: u32,9803 tag_ty_index: u32,
9767 type_name_extra_index: u32,9804 type_name_extra_index: u32,
9768 namespace_extra_index: u32,9805 namespace_extra_index: u32,
9806 name_nav_extra_index: u32,
9769 names_map: MapIndex,9807 names_map: MapIndex,
9770 names_start: u32,9808 names_start: u32,
9771 values_map: OptionalMapIndex,9809 values_map: OptionalMapIndex,
...@@ -9775,10 +9813,13 @@ pub const WipEnumType = struct {...@@ -9775,10 +9813,13 @@ pub const WipEnumType = struct {
9775 wip: WipEnumType,9813 wip: WipEnumType,
9776 ip: *InternPool,9814 ip: *InternPool,
9777 type_name: NullTerminatedString,9815 type_name: NullTerminatedString,
9816 /// This should be the `Nav` we are named after if we use the `.parent` name strategy; `.none` otherwise.
9817 name_nav: Nav.Index.Optional,
9778 ) void {9818 ) void {
9779 const extra = ip.getLocalShared(wip.tid).extra.acquire();9819 const extra = ip.getLocalShared(wip.tid).extra.acquire();
9780 const extra_items = extra.view().items(.@"0");9820 const extra_items = extra.view().items(.@"0");
9781 extra_items[wip.type_name_extra_index] = @intFromEnum(type_name);9821 extra_items[wip.type_name_extra_index] = @intFromEnum(type_name);
9822 extra_items[wip.name_nav_extra_index] = @intFromEnum(name_nav);
9782 }9823 }
97839824
9784 pub fn prepare(9825 pub fn prepare(
...@@ -9893,6 +9934,7 @@ pub fn getEnumType(...@@ -9893,6 +9934,7 @@ pub fn getEnumType(
98939934
9894 const extra_index = addExtraAssumeCapacity(extra, EnumAuto{9935 const extra_index = addExtraAssumeCapacity(extra, EnumAuto{
9895 .name = undefined, // set by `prepare`9936 .name = undefined, // set by `prepare`
9937 .name_nav = undefined, // set by `prepare`
9896 .captures_len = switch (ini.key) {9938 .captures_len = switch (ini.key) {
9897 inline .declared, .declared_owned_captures => |d| @intCast(d.captures.len),9939 inline .declared, .declared_owned_captures => |d| @intCast(d.captures.len),
9898 .reified => std.math.maxInt(u32),9940 .reified => std.math.maxInt(u32),
...@@ -9921,6 +9963,7 @@ pub fn getEnumType(...@@ -9921,6 +9963,7 @@ pub fn getEnumType(
9921 .index = gop.put(),9963 .index = gop.put(),
9922 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,9964 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
9923 .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "name").?,9965 .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "name").?,
9966 .name_nav_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "name_nav").?,
9924 .namespace_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "namespace").?,9967 .namespace_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "namespace").?,
9925 .names_map = names_map,9968 .names_map = names_map,
9926 .names_start = @intCast(names_start),9969 .names_start = @intCast(names_start),
...@@ -9950,6 +9993,7 @@ pub fn getEnumType(...@@ -9950,6 +9993,7 @@ pub fn getEnumType(
99509993
9951 const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{9994 const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{
9952 .name = undefined, // set by `prepare`9995 .name = undefined, // set by `prepare`
9996 .name_nav = undefined, // set by `prepare`
9953 .captures_len = switch (ini.key) {9997 .captures_len = switch (ini.key) {
9954 inline .declared, .declared_owned_captures => |d| @intCast(d.captures.len),9998 inline .declared, .declared_owned_captures => |d| @intCast(d.captures.len),
9955 .reified => std.math.maxInt(u32),9999 .reified => std.math.maxInt(u32),
...@@ -9987,6 +10031,7 @@ pub fn getEnumType(...@@ -9987,6 +10031,7 @@ pub fn getEnumType(
9987 .index = gop.put(),10031 .index = gop.put(),
9988 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumExplicit, "int_tag_type").?,10032 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumExplicit, "int_tag_type").?,
9989 .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "name").?,10033 .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "name").?,
10034 .name_nav_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "name_nav").?,
9990 .namespace_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "namespace").?,10035 .namespace_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "namespace").?,
9991 .names_map = names_map,10036 .names_map = names_map,
9992 .names_start = @intCast(names_start),10037 .names_start = @intCast(names_start),
...@@ -10055,6 +10100,7 @@ pub fn getGeneratedTagEnumType(...@@ -10055,6 +10100,7 @@ pub fn getGeneratedTagEnumType(
10055 .tag = .type_enum_auto,10100 .tag = .type_enum_auto,
10056 .data = addExtraAssumeCapacity(extra, EnumAuto{10101 .data = addExtraAssumeCapacity(extra, EnumAuto{
10057 .name = ini.name,10102 .name = ini.name,
10103 .name_nav = .none,
10058 .captures_len = 0,10104 .captures_len = 0,
10059 .namespace = namespace,10105 .namespace = namespace,
10060 .int_tag_type = ini.tag_ty,10106 .int_tag_type = ini.tag_ty,
...@@ -10088,6 +10134,7 @@ pub fn getGeneratedTagEnumType(...@@ -10088,6 +10134,7 @@ pub fn getGeneratedTagEnumType(
10088 },10134 },
10089 .data = addExtraAssumeCapacity(extra, EnumExplicit{10135 .data = addExtraAssumeCapacity(extra, EnumExplicit{
10090 .name = ini.name,10136 .name = ini.name,
10137 .name_nav = .none,
10091 .captures_len = 0,10138 .captures_len = 0,
10092 .namespace = namespace,10139 .namespace = namespace,
10093 .int_tag_type = ini.tag_ty,10140 .int_tag_type = ini.tag_ty,
...@@ -10161,6 +10208,7 @@ pub fn getOpaqueType(...@@ -10161,6 +10208,7 @@ pub fn getOpaqueType(
10161 });10208 });
10162 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{10209 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{
10163 .name = undefined, // set by `finish`10210 .name = undefined, // set by `finish`
10211 .name_nav = undefined, // set by `finish`
10164 .namespace = undefined, // set by `finish`10212 .namespace = undefined, // set by `finish`
10165 .zir_index = switch (ini.key) {10213 .zir_index = switch (ini.key) {
10166 inline else => |x| x.zir_index,10214 inline else => |x| x.zir_index,
...@@ -10183,6 +10231,7 @@ pub fn getOpaqueType(...@@ -10183,6 +10231,7 @@ pub fn getOpaqueType(
10183 .tid = tid,10231 .tid = tid,
10184 .index = gop.put(),10232 .index = gop.put(),
10185 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "name").?,10233 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "name").?,
10234 .name_nav_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "name_nav").?,
10186 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?,10235 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?,
10187 },10236 },
10188 };10237 };
...@@ -10299,6 +10348,7 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {...@@ -10299,6 +10348,7 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
10299 extra.appendAssumeCapacity(.{switch (field.type) {10348 extra.appendAssumeCapacity(.{switch (field.type) {
10300 Index,10349 Index,
10301 Nav.Index,10350 Nav.Index,
10351 Nav.Index.Optional,
10302 NamespaceIndex,10352 NamespaceIndex,
10303 OptionalNamespaceIndex,10353 OptionalNamespaceIndex,
10304 MapIndex,10354 MapIndex,
...@@ -10361,6 +10411,7 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat...@@ -10361,6 +10411,7 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat
10361 @field(result, field.name) = switch (field.type) {10411 @field(result, field.name) = switch (field.type) {
10362 Index,10412 Index,
10363 Nav.Index,10413 Nav.Index,
10414 Nav.Index.Optional,
10364 NamespaceIndex,10415 NamespaceIndex,
10365 OptionalNamespaceIndex,10416 OptionalNamespaceIndex,
10366 MapIndex,10417 MapIndex,
src/Sema.zig+85-47
...@@ -2963,13 +2963,14 @@ fn zirStructDecl(...@@ -2963,13 +2963,14 @@ fn zirStructDecl(
2963 };2963 };
2964 errdefer wip_ty.cancel(ip, pt.tid);2964 errdefer wip_ty.cancel(ip, pt.tid);
29652965
2966 wip_ty.setName(ip, try sema.createTypeName(2966 const type_name = try sema.createTypeName(
2967 block,2967 block,
2968 small.name_strategy,2968 small.name_strategy,
2969 "struct",2969 "struct",
2970 inst,2970 inst,
2971 wip_ty.index,2971 wip_ty.index,
2972 ));2972 );
2973 wip_ty.setName(ip, type_name.name, type_name.nav);
29732974
2974 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{2975 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
2975 .parent = block.namespace.toOptional(),2976 .parent = block.namespace.toOptional(),
...@@ -2991,7 +2992,8 @@ fn zirStructDecl(...@@ -2991,7 +2992,8 @@ fn zirStructDecl(
2991 if (zcu.comp.config.use_llvm) break :codegen_type;2992 if (zcu.comp.config.use_llvm) break :codegen_type;
2992 if (block.ownerModule().strip) break :codegen_type;2993 if (block.ownerModule().strip) break :codegen_type;
2993 // This job depends on any resolve_type_fully jobs queued up before it.2994 // This job depends on any resolve_type_fully jobs queued up before it.
2994 try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index });2995 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
2996 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
2995 }2997 }
2996 try sema.declareDependency(.{ .interned = wip_ty.index });2998 try sema.declareDependency(.{ .interned = wip_ty.index });
2997 try sema.addTypeReferenceEntry(src, wip_ty.index);2999 try sema.addTypeReferenceEntry(src, wip_ty.index);
...@@ -3007,7 +3009,10 @@ pub fn createTypeName(...@@ -3007,7 +3009,10 @@ pub fn createTypeName(
3007 inst: ?Zir.Inst.Index,3009 inst: ?Zir.Inst.Index,
3008 /// This is used purely to give the type a unique name in the `anon` case.3010 /// This is used purely to give the type a unique name in the `anon` case.
3009 type_index: InternPool.Index,3011 type_index: InternPool.Index,
3010) !InternPool.NullTerminatedString {3012) !struct {
3013 name: InternPool.NullTerminatedString,
3014 nav: InternPool.Nav.Index.Optional,
3015} {
3011 const pt = sema.pt;3016 const pt = sema.pt;
3012 const zcu = pt.zcu;3017 const zcu = pt.zcu;
3013 const gpa = zcu.gpa;3018 const gpa = zcu.gpa;
...@@ -3015,7 +3020,10 @@ pub fn createTypeName(...@@ -3015,7 +3020,10 @@ pub fn createTypeName(
30153020
3016 switch (name_strategy) {3021 switch (name_strategy) {
3017 .anon => {}, // handled after switch3022 .anon => {}, // handled after switch
3018 .parent => return block.type_name_ctx,3023 .parent => return .{
3024 .name = block.type_name_ctx,
3025 .nav = sema.owner.unwrap().nav_val.toOptional(),
3026 },
3019 .func => func_strat: {3027 .func => func_strat: {
3020 const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip) orelse return error.AnalysisFail);3028 const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip) orelse return error.AnalysisFail);
3021 const zir_tags = sema.code.instructions.items(.tag);3029 const zir_tags = sema.code.instructions.items(.tag);
...@@ -3057,7 +3065,10 @@ pub fn createTypeName(...@@ -3057,7 +3065,10 @@ pub fn createTypeName(
3057 };3065 };
30583066
3059 try writer.writeByte(')');3067 try writer.writeByte(')');
3060 return ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls);3068 return .{
3069 .name = try ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls),
3070 .nav = .none,
3071 };
3061 },3072 },
3062 .dbg_var => {3073 .dbg_var => {
3063 // TODO: this logic is questionable. We ideally should be traversing the `Block` rather than relying on the order of AstGen instructions.3074 // TODO: this logic is questionable. We ideally should be traversing the `Block` rather than relying on the order of AstGen instructions.
...@@ -3066,9 +3077,12 @@ pub fn createTypeName(...@@ -3066,9 +3077,12 @@ pub fn createTypeName(
3066 const zir_data = sema.code.instructions.items(.data);3077 const zir_data = sema.code.instructions.items(.data);
3067 for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) {3078 for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) {
3068 .dbg_var_ptr, .dbg_var_val => if (zir_data[i].str_op.operand == ref) {3079 .dbg_var_ptr, .dbg_var_val => if (zir_data[i].str_op.operand == ref) {
3069 return ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{3080 return .{
3070 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),3081 .name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{
3071 }, .no_embedded_nulls);3082 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
3083 }, .no_embedded_nulls),
3084 .nav = .none,
3085 };
3072 },3086 },
3073 else => {},3087 else => {},
3074 };3088 };
...@@ -3086,9 +3100,12 @@ pub fn createTypeName(...@@ -3086,9 +3100,12 @@ pub fn createTypeName(
3086 // types appropriately. However, `@typeName` becomes a problem then. If we remove3100 // types appropriately. However, `@typeName` becomes a problem then. If we remove
3087 // that builtin from the language, we can consider this.3101 // that builtin from the language, we can consider this.
30883102
3089 return ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{3103 return .{
3090 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(type_index),3104 .name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{
3091 }, .no_embedded_nulls);3105 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(type_index),
3106 }, .no_embedded_nulls),
3107 .nav = .none,
3108 };
3092}3109}
30933110
3094fn zirEnumDecl(3111fn zirEnumDecl(
...@@ -3209,7 +3226,7 @@ fn zirEnumDecl(...@@ -3209,7 +3226,7 @@ fn zirEnumDecl(
3209 inst,3226 inst,
3210 wip_ty.index,3227 wip_ty.index,
3211 );3228 );
3212 wip_ty.setName(ip, type_name);3229 wip_ty.setName(ip, type_name.name, type_name.nav);
32133230
3214 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{3231 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
3215 .parent = block.namespace.toOptional(),3232 .parent = block.namespace.toOptional(),
...@@ -3236,7 +3253,7 @@ fn zirEnumDecl(...@@ -3236,7 +3253,7 @@ fn zirEnumDecl(
3236 inst,3253 inst,
3237 tracked_inst,3254 tracked_inst,
3238 new_namespace_index,3255 new_namespace_index,
3239 type_name,3256 type_name.name,
3240 small,3257 small,
3241 body,3258 body,
3242 tag_type_ref,3259 tag_type_ref,
...@@ -3250,7 +3267,8 @@ fn zirEnumDecl(...@@ -3250,7 +3267,8 @@ fn zirEnumDecl(
3250 if (zcu.comp.config.use_llvm) break :codegen_type;3267 if (zcu.comp.config.use_llvm) break :codegen_type;
3251 if (block.ownerModule().strip) break :codegen_type;3268 if (block.ownerModule().strip) break :codegen_type;
3252 // This job depends on any resolve_type_fully jobs queued up before it.3269 // This job depends on any resolve_type_fully jobs queued up before it.
3253 try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index });3270 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
3271 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
3254 }3272 }
3255 return Air.internedToRef(wip_ty.index);3273 return Air.internedToRef(wip_ty.index);
3256}3274}
...@@ -3340,13 +3358,14 @@ fn zirUnionDecl(...@@ -3340,13 +3358,14 @@ fn zirUnionDecl(
3340 };3358 };
3341 errdefer wip_ty.cancel(ip, pt.tid);3359 errdefer wip_ty.cancel(ip, pt.tid);
33423360
3343 wip_ty.setName(ip, try sema.createTypeName(3361 const type_name = try sema.createTypeName(
3344 block,3362 block,
3345 small.name_strategy,3363 small.name_strategy,
3346 "union",3364 "union",
3347 inst,3365 inst,
3348 wip_ty.index,3366 wip_ty.index,
3349 ));3367 );
3368 wip_ty.setName(ip, type_name.name, type_name.nav);
33503369
3351 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{3370 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
3352 .parent = block.namespace.toOptional(),3371 .parent = block.namespace.toOptional(),
...@@ -3368,7 +3387,8 @@ fn zirUnionDecl(...@@ -3368,7 +3387,8 @@ fn zirUnionDecl(
3368 if (zcu.comp.config.use_llvm) break :codegen_type;3387 if (zcu.comp.config.use_llvm) break :codegen_type;
3369 if (block.ownerModule().strip) break :codegen_type;3388 if (block.ownerModule().strip) break :codegen_type;
3370 // This job depends on any resolve_type_fully jobs queued up before it.3389 // This job depends on any resolve_type_fully jobs queued up before it.
3371 try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index });3390 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
3391 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
3372 }3392 }
3373 try sema.declareDependency(.{ .interned = wip_ty.index });3393 try sema.declareDependency(.{ .interned = wip_ty.index });
3374 try sema.addTypeReferenceEntry(src, wip_ty.index);3394 try sema.addTypeReferenceEntry(src, wip_ty.index);
...@@ -3432,13 +3452,14 @@ fn zirOpaqueDecl(...@@ -3432,13 +3452,14 @@ fn zirOpaqueDecl(
3432 };3452 };
3433 errdefer wip_ty.cancel(ip, pt.tid);3453 errdefer wip_ty.cancel(ip, pt.tid);
34343454
3435 wip_ty.setName(ip, try sema.createTypeName(3455 const type_name = try sema.createTypeName(
3436 block,3456 block,
3437 small.name_strategy,3457 small.name_strategy,
3438 "opaque",3458 "opaque",
3439 inst,3459 inst,
3440 wip_ty.index,3460 wip_ty.index,
3441 ));3461 );
3462 wip_ty.setName(ip, type_name.name, type_name.nav);
34423463
3443 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{3464 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
3444 .parent = block.namespace.toOptional(),3465 .parent = block.namespace.toOptional(),
...@@ -3455,7 +3476,8 @@ fn zirOpaqueDecl(...@@ -3455,7 +3476,8 @@ fn zirOpaqueDecl(
3455 if (zcu.comp.config.use_llvm) break :codegen_type;3476 if (zcu.comp.config.use_llvm) break :codegen_type;
3456 if (block.ownerModule().strip) break :codegen_type;3477 if (block.ownerModule().strip) break :codegen_type;
3457 // This job depends on any resolve_type_fully jobs queued up before it.3478 // This job depends on any resolve_type_fully jobs queued up before it.
3458 try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index });3479 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
3480 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
3459 }3481 }
3460 try sema.addTypeReferenceEntry(src, wip_ty.index);3482 try sema.addTypeReferenceEntry(src, wip_ty.index);
3461 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);3483 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
...@@ -20052,7 +20074,8 @@ fn structInitAnon(...@@ -20052,7 +20074,8 @@ fn structInitAnon(
20052 }, false)) {20074 }, false)) {
20053 .wip => |wip| ty: {20075 .wip => |wip| ty: {
20054 errdefer wip.cancel(ip, pt.tid);20076 errdefer wip.cancel(ip, pt.tid);
20055 wip.setName(ip, try sema.createTypeName(block, .anon, "struct", inst, wip.index));20077 const type_name = try sema.createTypeName(block, .anon, "struct", inst, wip.index);
20078 wip.setName(ip, type_name.name, type_name.nav);
2005620079
20057 const struct_type = ip.loadStructType(wip.index);20080 const struct_type = ip.loadStructType(wip.index);
2005820081
...@@ -20076,7 +20099,8 @@ fn structInitAnon(...@@ -20076,7 +20099,8 @@ fn structInitAnon(
20076 codegen_type: {20099 codegen_type: {
20077 if (zcu.comp.config.use_llvm) break :codegen_type;20100 if (zcu.comp.config.use_llvm) break :codegen_type;
20078 if (block.ownerModule().strip) break :codegen_type;20101 if (block.ownerModule().strip) break :codegen_type;
20079 try zcu.comp.queueJob(.{ .codegen_type = wip.index });20102 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
20103 try zcu.comp.queueJob(.{ .link_type = wip.index });
20080 }20104 }
20081 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);20105 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
20082 break :ty wip.finish(ip, new_namespace_index);20106 break :ty wip.finish(ip, new_namespace_index);
...@@ -21112,13 +21136,14 @@ fn zirReify(...@@ -21112,13 +21136,14 @@ fn zirReify(
21112 };21136 };
21113 errdefer wip_ty.cancel(ip, pt.tid);21137 errdefer wip_ty.cancel(ip, pt.tid);
2111421138
21115 wip_ty.setName(ip, try sema.createTypeName(21139 const type_name = try sema.createTypeName(
21116 block,21140 block,
21117 name_strategy,21141 name_strategy,
21118 "opaque",21142 "opaque",
21119 inst,21143 inst,
21120 wip_ty.index,21144 wip_ty.index,
21121 ));21145 );
21146 wip_ty.setName(ip, type_name.name, type_name.nav);
2112221147
21123 const new_namespace_index = try pt.createNamespace(.{21148 const new_namespace_index = try pt.createNamespace(.{
21124 .parent = block.namespace.toOptional(),21149 .parent = block.namespace.toOptional(),
...@@ -21317,13 +21342,14 @@ fn reifyEnum(...@@ -21317,13 +21342,14 @@ fn reifyEnum(
21317 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});21342 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});
21318 }21343 }
2131921344
21320 wip_ty.setName(ip, try sema.createTypeName(21345 const type_name = try sema.createTypeName(
21321 block,21346 block,
21322 name_strategy,21347 name_strategy,
21323 "enum",21348 "enum",
21324 inst,21349 inst,
21325 wip_ty.index,21350 wip_ty.index,
21326 ));21351 );
21352 wip_ty.setName(ip, type_name.name, type_name.nav);
2132721353
21328 const new_namespace_index = try pt.createNamespace(.{21354 const new_namespace_index = try pt.createNamespace(.{
21329 .parent = block.namespace.toOptional(),21355 .parent = block.namespace.toOptional(),
...@@ -21386,7 +21412,8 @@ fn reifyEnum(...@@ -21386,7 +21412,8 @@ fn reifyEnum(
21386 if (zcu.comp.config.use_llvm) break :codegen_type;21412 if (zcu.comp.config.use_llvm) break :codegen_type;
21387 if (block.ownerModule().strip) break :codegen_type;21413 if (block.ownerModule().strip) break :codegen_type;
21388 // This job depends on any resolve_type_fully jobs queued up before it.21414 // This job depends on any resolve_type_fully jobs queued up before it.
21389 try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index });21415 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
21416 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
21390 }21417 }
21391 return Air.internedToRef(wip_ty.index);21418 return Air.internedToRef(wip_ty.index);
21392}21419}
...@@ -21488,7 +21515,7 @@ fn reifyUnion(...@@ -21488,7 +21515,7 @@ fn reifyUnion(
21488 inst,21515 inst,
21489 wip_ty.index,21516 wip_ty.index,
21490 );21517 );
21491 wip_ty.setName(ip, type_name);21518 wip_ty.setName(ip, type_name.name, type_name.nav);
2149221519
21493 const field_types = try sema.arena.alloc(InternPool.Index, fields_len);21520 const field_types = try sema.arena.alloc(InternPool.Index, fields_len);
21494 const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined;21521 const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined;
...@@ -21581,7 +21608,7 @@ fn reifyUnion(...@@ -21581,7 +21608,7 @@ fn reifyUnion(
21581 }21608 }
21582 }21609 }
2158321610
21584 const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), wip_ty.index, type_name);21611 const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), wip_ty.index, type_name.name);
21585 break :tag_ty .{ enum_tag_ty, false };21612 break :tag_ty .{ enum_tag_ty, false };
21586 };21613 };
21587 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error21614 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
...@@ -21640,7 +21667,8 @@ fn reifyUnion(...@@ -21640,7 +21667,8 @@ fn reifyUnion(
21640 if (zcu.comp.config.use_llvm) break :codegen_type;21667 if (zcu.comp.config.use_llvm) break :codegen_type;
21641 if (block.ownerModule().strip) break :codegen_type;21668 if (block.ownerModule().strip) break :codegen_type;
21642 // This job depends on any resolve_type_fully jobs queued up before it.21669 // This job depends on any resolve_type_fully jobs queued up before it.
21643 try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index });21670 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
21671 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
21644 }21672 }
21645 try sema.declareDependency(.{ .interned = wip_ty.index });21673 try sema.declareDependency(.{ .interned = wip_ty.index });
21646 try sema.addTypeReferenceEntry(src, wip_ty.index);21674 try sema.addTypeReferenceEntry(src, wip_ty.index);
...@@ -21843,13 +21871,14 @@ fn reifyStruct(...@@ -21843,13 +21871,14 @@ fn reifyStruct(
21843 };21871 };
21844 errdefer wip_ty.cancel(ip, pt.tid);21872 errdefer wip_ty.cancel(ip, pt.tid);
2184521873
21846 wip_ty.setName(ip, try sema.createTypeName(21874 const type_name = try sema.createTypeName(
21847 block,21875 block,
21848 name_strategy,21876 name_strategy,
21849 "struct",21877 "struct",
21850 inst,21878 inst,
21851 wip_ty.index,21879 wip_ty.index,
21852 ));21880 );
21881 wip_ty.setName(ip, type_name.name, type_name.nav);
2185321882
21854 const struct_type = ip.loadStructType(wip_ty.index);21883 const struct_type = ip.loadStructType(wip_ty.index);
2185521884
...@@ -21994,7 +22023,8 @@ fn reifyStruct(...@@ -21994,7 +22023,8 @@ fn reifyStruct(
21994 if (zcu.comp.config.use_llvm) break :codegen_type;22023 if (zcu.comp.config.use_llvm) break :codegen_type;
21995 if (block.ownerModule().strip) break :codegen_type;22024 if (block.ownerModule().strip) break :codegen_type;
21996 // This job depends on any resolve_type_fully jobs queued up before it.22025 // This job depends on any resolve_type_fully jobs queued up before it.
21997 try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index });22026 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
22027 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
21998 }22028 }
21999 try sema.declareDependency(.{ .interned = wip_ty.index });22029 try sema.declareDependency(.{ .interned = wip_ty.index });
22000 try sema.addTypeReferenceEntry(src, wip_ty.index);22030 try sema.addTypeReferenceEntry(src, wip_ty.index);
...@@ -35022,7 +35052,7 @@ pub fn resolveUnionAlignment(...@@ -35022,7 +35052,7 @@ pub fn resolveUnionAlignment(
35022 union_type.setAlignment(ip, max_align);35052 union_type.setAlignment(ip, max_align);
35023}35053}
3502435054
35025/// This logic must be kept in sync with `Zcu.getUnionLayout`.35055/// This logic must be kept in sync with `Type.getUnionLayout`.
35026pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {35056pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35027 const pt = sema.pt;35057 const pt = sema.pt;
35028 const ip = &pt.zcu.intern_pool;35058 const ip = &pt.zcu.intern_pool;
...@@ -35056,24 +35086,32 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35056,24 +35086,32 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35056 var max_align: Alignment = .@"1";35086 var max_align: Alignment = .@"1";
35057 for (0..union_type.field_types.len) |field_index| {35087 for (0..union_type.field_types.len) |field_index| {
35058 const field_ty: Type = .fromInterned(union_type.field_types.get(ip)[field_index]);35088 const field_ty: Type = .fromInterned(union_type.field_types.get(ip)[field_index]);
3505935089 if (field_ty.isNoReturn(pt.zcu)) continue;
35060 if (try field_ty.comptimeOnlySema(pt) or field_ty.zigTypeTag(pt.zcu) == .noreturn) continue; // TODO: should this affect alignment?35090
3506135091 // We need to call `hasRuntimeBits` before calling `abiSize` to prevent reachable `unreachable`s,
35062 max_size = @max(max_size, field_ty.abiSizeSema(pt) catch |err| switch (err) {35092 // but `hasRuntimeBits` only resolves field types and so may infinite recurse on a layout wip type,
35063 error.AnalysisFail => {35093 // so we must resolve the layout manually first, instead of waiting for `abiSize` to do it for us.
35064 const msg = sema.err orelse return err;35094 // This is arguably just hacking around bugs in both `abiSize` for not allowing arbitrary types to
35065 try sema.addFieldErrNote(ty, field_index, msg, "while checking this field", .{});35095 // be queried, enabling failures to be handled with the emission of a compile error, and also in
35066 return err;35096 // `hasRuntimeBits` for ever being able to infinite recurse in the first place.
35067 },35097 try field_ty.resolveLayout(pt);
35068 else => return err,35098
35069 });35099 if (try field_ty.hasRuntimeBitsSema(pt)) {
35100 max_size = @max(max_size, field_ty.abiSizeSema(pt) catch |err| switch (err) {
35101 error.AnalysisFail => {
35102 const msg = sema.err orelse return err;
35103 try sema.addFieldErrNote(ty, field_index, msg, "while checking this field", .{});
35104 return err;
35105 },
35106 else => return err,
35107 });
35108 }
3507035109
35071 const explicit_align = union_type.fieldAlign(ip, field_index);35110 const explicit_align = union_type.fieldAlign(ip, field_index);
35072 const field_align = if (explicit_align != .none)35111 const field_align = if (explicit_align != .none)
35073 explicit_align35112 explicit_align
35074 else35113 else
35075 try field_ty.abiAlignmentSema(pt);35114 try field_ty.abiAlignmentSema(pt);
35076
35077 max_align = max_align.max(field_align);35115 max_align = max_align.max(field_align);
35078 }35116 }
3507935117
src/Sema/LowerZon.zig+5-3
...@@ -157,13 +157,14 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter...@@ -157,13 +157,14 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
157 )) {157 )) {
158 .wip => |wip| ty: {158 .wip => |wip| ty: {
159 errdefer wip.cancel(ip, pt.tid);159 errdefer wip.cancel(ip, pt.tid);
160 wip.setName(ip, try self.sema.createTypeName(160 const type_name = try self.sema.createTypeName(
161 self.block,161 self.block,
162 .anon,162 .anon,
163 "struct",163 "struct",
164 self.base_node_inst.resolve(ip),164 self.base_node_inst.resolve(ip),
165 wip.index,165 wip.index,
166 ));166 );
167 wip.setName(ip, type_name.name, type_name.nav);
167168
168 const struct_type = ip.loadStructType(wip.index);169 const struct_type = ip.loadStructType(wip.index);
169170
...@@ -194,7 +195,8 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter...@@ -194,7 +195,8 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
194 codegen_type: {195 codegen_type: {
195 if (pt.zcu.comp.config.use_llvm) break :codegen_type;196 if (pt.zcu.comp.config.use_llvm) break :codegen_type;
196 if (self.block.ownerModule().strip) break :codegen_type;197 if (self.block.ownerModule().strip) break :codegen_type;
197 try pt.zcu.comp.queueJob(.{ .codegen_type = wip.index });198 pt.zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
199 try pt.zcu.comp.queueJob(.{ .link_type = wip.index });
198 }200 }
199 break :ty wip.finish(ip, new_namespace_index);201 break :ty wip.finish(ip, new_namespace_index);
200 },202 },
src/ThreadSafeQueue.zig deleted-72
...@@ -1,72 +0,0 @@
1const std = @import("std");
2const assert = std.debug.assert;
3const Allocator = std.mem.Allocator;
4
5pub fn ThreadSafeQueue(comptime T: type) type {
6 return struct {
7 worker_owned: std.ArrayListUnmanaged(T),
8 /// Protected by `mutex`.
9 shared: std.ArrayListUnmanaged(T),
10 mutex: std.Thread.Mutex,
11 state: State,
12
13 const Self = @This();
14
15 pub const State = enum { wait, run };
16
17 pub const empty: Self = .{
18 .worker_owned = .empty,
19 .shared = .empty,
20 .mutex = .{},
21 .state = .wait,
22 };
23
24 pub fn deinit(self: *Self, gpa: Allocator) void {
25 self.worker_owned.deinit(gpa);
26 self.shared.deinit(gpa);
27 self.* = undefined;
28 }
29
30 /// Must be called from the worker thread.
31 pub fn check(self: *Self) ?[]T {
32 assert(self.worker_owned.items.len == 0);
33 {
34 self.mutex.lock();
35 defer self.mutex.unlock();
36 assert(self.state == .run);
37 if (self.shared.items.len == 0) {
38 self.state = .wait;
39 return null;
40 }
41 std.mem.swap(std.ArrayListUnmanaged(T), &self.worker_owned, &self.shared);
42 }
43 const result = self.worker_owned.items;
44 self.worker_owned.clearRetainingCapacity();
45 return result;
46 }
47
48 /// Adds items to the queue, returning true if and only if the worker
49 /// thread is waiting. Thread-safe.
50 /// Not safe to call from the worker thread.
51 pub fn enqueue(self: *Self, gpa: Allocator, items: []const T) error{OutOfMemory}!bool {
52 self.mutex.lock();
53 defer self.mutex.unlock();
54 try self.shared.appendSlice(gpa, items);
55 return switch (self.state) {
56 .run => false,
57 .wait => {
58 self.state = .run;
59 return true;
60 },
61 };
62 }
63
64 /// Safe only to call exactly once when initially starting the worker.
65 pub fn start(self: *Self) bool {
66 assert(self.state == .wait);
67 if (self.shared.items.len == 0) return false;
68 self.state = .run;
69 return true;
70 }
71 };
72}
src/Type.zig+13-10
...@@ -177,6 +177,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error...@@ -177,6 +177,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
177 const zcu = pt.zcu;177 const zcu = pt.zcu;
178 const ip = &zcu.intern_pool;178 const ip = &zcu.intern_pool;
179 switch (ip.indexToKey(ty.toIntern())) {179 switch (ip.indexToKey(ty.toIntern())) {
180 .undef => return writer.writeAll("@as(type, undefined)"),
180 .int_type => |int_type| {181 .int_type => |int_type| {
181 const sign_char: u8 = switch (int_type.signedness) {182 const sign_char: u8 = switch (int_type.signedness) {
182 .signed => 'i',183 .signed => 'i',
...@@ -398,7 +399,6 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error...@@ -398,7 +399,6 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
398 },399 },
399400
400 // values, not types401 // values, not types
401 .undef,
402 .simple_value,402 .simple_value,
403 .variable,403 .variable,
404 .@"extern",404 .@"extern",
...@@ -3915,29 +3915,32 @@ fn resolveUnionInner(...@@ -3915,29 +3915,32 @@ fn resolveUnionInner(
3915pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu) Zcu.UnionLayout {3915pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu) Zcu.UnionLayout {
3916 const ip = &zcu.intern_pool;3916 const ip = &zcu.intern_pool;
3917 assert(loaded_union.haveLayout(ip));3917 assert(loaded_union.haveLayout(ip));
3918 var most_aligned_field: u32 = undefined;3918 var most_aligned_field: u32 = 0;
3919 var most_aligned_field_size: u64 = undefined;3919 var most_aligned_field_align: InternPool.Alignment = .@"1";
3920 var biggest_field: u32 = undefined;3920 var most_aligned_field_size: u64 = 0;
3921 var biggest_field: u32 = 0;
3921 var payload_size: u64 = 0;3922 var payload_size: u64 = 0;
3922 var payload_align: InternPool.Alignment = .@"1";3923 var payload_align: InternPool.Alignment = .@"1";
3923 for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| {3924 for (loaded_union.field_types.get(ip), 0..) |field_ty_ip_index, field_index| {
3924 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue;3925 const field_ty: Type = .fromInterned(field_ty_ip_index);
3926 if (field_ty.isNoReturn(zcu)) continue;
39253927
3926 const explicit_align = loaded_union.fieldAlign(ip, field_index);3928 const explicit_align = loaded_union.fieldAlign(ip, field_index);
3927 const field_align = if (explicit_align != .none)3929 const field_align = if (explicit_align != .none)
3928 explicit_align3930 explicit_align
3929 else3931 else
3930 Type.fromInterned(field_ty).abiAlignment(zcu);3932 field_ty.abiAlignment(zcu);
3931 const field_size = Type.fromInterned(field_ty).abiSize(zcu);3933 const field_size = field_ty.abiSize(zcu);
3932 if (field_size > payload_size) {3934 if (field_size > payload_size) {
3933 payload_size = field_size;3935 payload_size = field_size;
3934 biggest_field = @intCast(field_index);3936 biggest_field = @intCast(field_index);
3935 }3937 }
3936 if (field_align.compare(.gte, payload_align)) {3938 if (field_size > 0 and field_align.compare(.gte, most_aligned_field_align)) {
3937 payload_align = field_align;
3938 most_aligned_field = @intCast(field_index);3939 most_aligned_field = @intCast(field_index);
3940 most_aligned_field_align = field_align;
3939 most_aligned_field_size = field_size;3941 most_aligned_field_size = field_size;
3940 }3942 }
3943 payload_align = payload_align.max(field_align);
3941 }3944 }
3942 const have_tag = loaded_union.flagsUnordered(ip).runtime_tag.hasTag();3945 const have_tag = loaded_union.flagsUnordered(ip).runtime_tag.hasTag();
3943 if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(zcu)) {3946 if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(zcu)) {
src/Zcu.zig+82-21
...@@ -56,9 +56,8 @@ comptime {...@@ -56,9 +56,8 @@ comptime {
56/// General-purpose allocator. Used for both temporary and long-term storage.56/// General-purpose allocator. Used for both temporary and long-term storage.
57gpa: Allocator,57gpa: Allocator,
58comp: *Compilation,58comp: *Compilation,
59/// Usually, the LlvmObject is managed by linker code, however, in the case59/// If the ZCU is emitting an LLVM object (i.e. we are using the LLVM backend), then this is the
60/// that -fno-emit-bin is specified, the linker code never executes, so we60/// `LlvmObject` we are emitting to.
61/// store the LlvmObject here.
62llvm_object: ?LlvmObject.Ptr,61llvm_object: ?LlvmObject.Ptr,
6362
64/// Pointer to externally managed resource.63/// Pointer to externally managed resource.
...@@ -67,8 +66,18 @@ root_mod: *Package.Module,...@@ -67,8 +66,18 @@ root_mod: *Package.Module,
67/// `root_mod` is the test runner, and `main_mod` is the user's source file which has the tests.66/// `root_mod` is the test runner, and `main_mod` is the user's source file which has the tests.
68main_mod: *Package.Module,67main_mod: *Package.Module,
69std_mod: *Package.Module,68std_mod: *Package.Module,
70sema_prog_node: std.Progress.Node = std.Progress.Node.none,69sema_prog_node: std.Progress.Node = .none,
71codegen_prog_node: std.Progress.Node = std.Progress.Node.none,70codegen_prog_node: std.Progress.Node = .none,
71/// The number of codegen jobs which are pending or in-progress. Whichever thread drops this value
72/// to 0 is responsible for ending `codegen_prog_node`. While semantic analysis is happening, this
73/// value bottoms out at 1 instead of 0, to ensure that it can only drop to 0 after analysis is
74/// completed (since semantic analysis could trigger more codegen work).
75pending_codegen_jobs: std.atomic.Value(u32) = .init(0),
76
77/// This is the progress node *under* `sema_prog_node` which is currently running.
78/// When we have to pause to analyze something else, we just temporarily rename this node.
79/// Eventually, when we thread semantic analysis, we will want one of these per thread.
80cur_sema_prog_node: std.Progress.Node = .none,
7281
73/// Used by AstGen worker to load and store ZIR cache.82/// Used by AstGen worker to load and store ZIR cache.
74global_zir_cache: Cache.Directory,83global_zir_cache: Cache.Directory,
...@@ -172,6 +181,8 @@ transitive_failed_analysis: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .emp...@@ -172,6 +181,8 @@ transitive_failed_analysis: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .emp
172/// This `Nav` succeeded analysis, but failed codegen.181/// This `Nav` succeeded analysis, but failed codegen.
173/// This may be a simple "value" `Nav`, or it may be a function.182/// This may be a simple "value" `Nav`, or it may be a function.
174/// The ErrorMsg memory is owned by the `AnalUnit`, using Module's general purpose allocator.183/// The ErrorMsg memory is owned by the `AnalUnit`, using Module's general purpose allocator.
184/// While multiple threads are active (most of the time!), this is guarded by `zcu.comp.mutex`, as
185/// codegen and linking run on a separate thread.
175failed_codegen: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, *ErrorMsg) = .empty,186failed_codegen: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, *ErrorMsg) = .empty,
176failed_types: std.AutoArrayHashMapUnmanaged(InternPool.Index, *ErrorMsg) = .empty,187failed_types: std.AutoArrayHashMapUnmanaged(InternPool.Index, *ErrorMsg) = .empty,
177/// Keep track of `@compileLog`s per `AnalUnit`.188/// Keep track of `@compileLog`s per `AnalUnit`.
...@@ -267,16 +278,6 @@ resolved_references: ?std.AutoHashMapUnmanaged(AnalUnit, ?ResolvedReference) = n...@@ -267,16 +278,6 @@ resolved_references: ?std.AutoHashMapUnmanaged(AnalUnit, ?ResolvedReference) = n
267/// Reset to `false` at the start of each update in `Compilation.update`.278/// Reset to `false` at the start of each update in `Compilation.update`.
268skip_analysis_this_update: bool = false,279skip_analysis_this_update: bool = false,
269280
270stage1_flags: packed struct {
271 have_winmain: bool = false,
272 have_wwinmain: bool = false,
273 have_winmain_crt_startup: bool = false,
274 have_wwinmain_crt_startup: bool = false,
275 have_dllmain_crt_startup: bool = false,
276 have_c_main: bool = false,
277 reserved: u2 = 0,
278} = .{},
279
280test_functions: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .empty,281test_functions: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .empty,
281282
282global_assembly: std.AutoArrayHashMapUnmanaged(AnalUnit, []u8) = .empty,283global_assembly: std.AutoArrayHashMapUnmanaged(AnalUnit, []u8) = .empty,
...@@ -3828,7 +3829,36 @@ pub const Feature = enum {...@@ -3828,7 +3829,36 @@ pub const Feature = enum {
3828 is_named_enum_value,3829 is_named_enum_value,
3829 error_set_has_value,3830 error_set_has_value,
3830 field_reordering,3831 field_reordering,
3831 /// If the backend supports running from another thread.3832 /// In theory, backends are supposed to work like this:
3833 ///
3834 /// * The AIR emitted by `Sema` is converted into MIR by `codegen.generateFunction`. This pass
3835 /// is "pure", in that it does not depend on or modify any external mutable state.
3836 ///
3837 /// * That MIR is sent to the linker, which calls `codegen.emitFunction` to convert the MIR to
3838 /// finalized machine code. This process is permitted to query and modify linker state.
3839 ///
3840 /// * The linker stores the resulting machine code in the binary as needed.
3841 ///
3842 /// The first stage described above can run in parallel to the rest of the compiler, and even to
3843 /// other code generation work; we can run as many codegen threads as we want in parallel because
3844 /// of the fact that this pass is pure. Emit and link must be single-threaded, but are generally
3845 /// very fast, so that isn't a problem.
3846 ///
3847 /// Unfortunately, some code generation implementations currently query and/or mutate linker state
3848 /// or even (in the case of the LLVM backend) semantic analysis state. Such backends cannot be run
3849 /// in parallel with each other, with linking, or (potentially) with semantic analysis.
3850 ///
3851 /// Additionally, some backends continue to need the AIR in the "emit" stage, despite this pass
3852 /// operating on MIR. This complicates memory management under the threading model above.
3853 ///
3854 /// These are both **bugs** in backend implementations, left over from legacy code. However, they
3855 /// are difficult to fix. So, this `Feature` currently guards correct threading of code generation:
3856 ///
3857 /// * With this feature enabled, the backend is threaded as described above. The "emit" stage does
3858 /// not have access to AIR (it will be `undefined`; see `codegen.emitFunction`).
3859 ///
3860 /// * With this feature disabled, semantic analysis, code generation, and linking all occur on the
3861 /// same thread, and the "emit" stage has access to AIR.
3832 separate_thread,3862 separate_thread,
3833};3863};
38343864
...@@ -4577,22 +4607,29 @@ pub fn codegenFail(...@@ -4577,22 +4607,29 @@ pub fn codegenFail(
4577 comptime format: []const u8,4607 comptime format: []const u8,
4578 args: anytype,4608 args: anytype,
4579) CodegenFailError {4609) CodegenFailError {
4580 const gpa = zcu.gpa;4610 const msg = try Zcu.ErrorMsg.create(zcu.gpa, zcu.navSrcLoc(nav_index), format, args);
4581 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);4611 return zcu.codegenFailMsg(nav_index, msg);
4582 const msg = try Zcu.ErrorMsg.create(gpa, zcu.navSrcLoc(nav_index), format, args);
4583 zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, msg);
4584 return error.CodegenFail;
4585}4612}
45864613
4614/// Takes ownership of `msg`, even on OOM.
4587pub fn codegenFailMsg(zcu: *Zcu, nav_index: InternPool.Nav.Index, msg: *ErrorMsg) CodegenFailError {4615pub fn codegenFailMsg(zcu: *Zcu, nav_index: InternPool.Nav.Index, msg: *ErrorMsg) CodegenFailError {
4588 const gpa = zcu.gpa;4616 const gpa = zcu.gpa;
4589 {4617 {
4618 zcu.comp.mutex.lock();
4619 defer zcu.comp.mutex.unlock();
4590 errdefer msg.deinit(gpa);4620 errdefer msg.deinit(gpa);
4591 try zcu.failed_codegen.putNoClobber(gpa, nav_index, msg);4621 try zcu.failed_codegen.putNoClobber(gpa, nav_index, msg);
4592 }4622 }
4593 return error.CodegenFail;4623 return error.CodegenFail;
4594}4624}
45954625
4626/// Asserts that `zcu.failed_codegen` contains the key `nav`, with the necessary lock held.
4627pub fn assertCodegenFailed(zcu: *Zcu, nav: InternPool.Nav.Index) void {
4628 zcu.comp.mutex.lock();
4629 defer zcu.comp.mutex.unlock();
4630 assert(zcu.failed_codegen.contains(nav));
4631}
4632
4596pub fn codegenFailType(4633pub fn codegenFailType(
4597 zcu: *Zcu,4634 zcu: *Zcu,
4598 ty_index: InternPool.Index,4635 ty_index: InternPool.Index,
...@@ -4726,3 +4763,27 @@ fn explainWhyFileIsInModule(...@@ -4726,3 +4763,27 @@ fn explainWhyFileIsInModule(
4726 import = importer_ref.import;4763 import = importer_ref.import;
4727 }4764 }
4728}4765}
4766
4767const SemaProgNode = struct {
4768 /// `null` means we created the node, so should end it.
4769 old_name: ?[std.Progress.Node.max_name_len]u8,
4770 pub fn end(spn: SemaProgNode, zcu: *Zcu) void {
4771 if (spn.old_name) |old_name| {
4772 zcu.sema_prog_node.completeOne(); // we're just renaming, but it's effectively completion
4773 zcu.cur_sema_prog_node.setName(&old_name);
4774 } else {
4775 zcu.cur_sema_prog_node.end();
4776 zcu.cur_sema_prog_node = .none;
4777 }
4778 }
4779};
4780pub fn startSemaProgNode(zcu: *Zcu, name: []const u8) SemaProgNode {
4781 if (zcu.cur_sema_prog_node.index != .none) {
4782 const old_name = zcu.cur_sema_prog_node.getName();
4783 zcu.cur_sema_prog_node.setName(name);
4784 return .{ .old_name = old_name };
4785 } else {
4786 zcu.cur_sema_prog_node = zcu.sema_prog_node.start(name, 0);
4787 return .{ .old_name = null };
4788 }
4789}
src/Zcu/PerThread.zig+189-216
...@@ -27,6 +27,7 @@ const Type = @import("../Type.zig");...@@ -27,6 +27,7 @@ const Type = @import("../Type.zig");
27const Value = @import("../Value.zig");27const Value = @import("../Value.zig");
28const Zcu = @import("../Zcu.zig");28const Zcu = @import("../Zcu.zig");
29const Compilation = @import("../Compilation.zig");29const Compilation = @import("../Compilation.zig");
30const codegen = @import("../codegen.zig");
30const Zir = std.zig.Zir;31const Zir = std.zig.Zir;
31const Zoir = std.zig.Zoir;32const Zoir = std.zig.Zoir;
32const ZonGen = std.zig.ZonGen;33const ZonGen = std.zig.ZonGen;
...@@ -795,8 +796,8 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU...@@ -795,8 +796,8 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU
795 info.deps.clearRetainingCapacity();796 info.deps.clearRetainingCapacity();
796 }797 }
797798
798 const unit_prog_node = zcu.sema_prog_node.start("comptime", 0);799 const unit_prog_node = zcu.startSemaProgNode("comptime");
799 defer unit_prog_node.end();800 defer unit_prog_node.end(zcu);
800801
801 return pt.analyzeComptimeUnit(cu_id) catch |err| switch (err) {802 return pt.analyzeComptimeUnit(cu_id) catch |err| switch (err) {
802 error.AnalysisFail => {803 error.AnalysisFail => {
...@@ -975,8 +976,8 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu...@@ -975,8 +976,8 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
975 info.deps.clearRetainingCapacity();976 info.deps.clearRetainingCapacity();
976 }977 }
977978
978 const unit_prog_node = zcu.sema_prog_node.start(nav.fqn.toSlice(ip), 0);979 const unit_prog_node = zcu.startSemaProgNode(nav.fqn.toSlice(ip));
979 defer unit_prog_node.end();980 defer unit_prog_node.end(zcu);
980981
981 const invalidate_value: bool, const new_failed: bool = if (pt.analyzeNavVal(nav_id)) |result| res: {982 const invalidate_value: bool, const new_failed: bool = if (pt.analyzeNavVal(nav_id)) |result| res: {
982 break :res .{983 break :res .{
...@@ -1320,7 +1321,8 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1320,7 +1321,8 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
1320 }1321 }
13211322
1322 // This job depends on any resolve_type_fully jobs queued up before it.1323 // This job depends on any resolve_type_fully jobs queued up before it.
1323 try zcu.comp.queueJob(.{ .codegen_nav = nav_id });1324 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
1325 try zcu.comp.queueJob(.{ .link_nav = nav_id });
1324 }1326 }
13251327
1326 switch (old_nav.status) {1328 switch (old_nav.status) {
...@@ -1395,8 +1397,8 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc...@@ -1395,8 +1397,8 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
1395 info.deps.clearRetainingCapacity();1397 info.deps.clearRetainingCapacity();
1396 }1398 }
13971399
1398 const unit_prog_node = zcu.sema_prog_node.start(nav.fqn.toSlice(ip), 0);1400 const unit_prog_node = zcu.startSemaProgNode(nav.fqn.toSlice(ip));
1399 defer unit_prog_node.end();1401 defer unit_prog_node.end(zcu);
14001402
1401 const invalidate_type: bool, const new_failed: bool = if (pt.analyzeNavType(nav_id)) |result| res: {1403 const invalidate_type: bool, const new_failed: bool = if (pt.analyzeNavType(nav_id)) |result| res: {
1402 break :res .{1404 break :res .{
...@@ -1616,8 +1618,8 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, maybe_coerced_func_index: Inter...@@ -1616,8 +1618,8 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
1616 info.deps.clearRetainingCapacity();1618 info.deps.clearRetainingCapacity();
1617 }1619 }
16181620
1619 const func_prog_node = zcu.sema_prog_node.start(ip.getNav(func.owner_nav).fqn.toSlice(ip), 0);1621 const func_prog_node = zcu.startSemaProgNode(ip.getNav(func.owner_nav).fqn.toSlice(ip));
1620 defer func_prog_node.end();1622 defer func_prog_node.end(zcu);
16211623
1622 const ies_outdated, const new_failed = if (pt.analyzeFuncBody(func_index)) |result|1624 const ies_outdated, const new_failed = if (pt.analyzeFuncBody(func_index)) |result|
1623 .{ prev_failed or result.ies_outdated, false }1625 .{ prev_failed or result.ies_outdated, false }
...@@ -1716,6 +1718,8 @@ fn analyzeFuncBody(...@@ -1716,6 +1718,8 @@ fn analyzeFuncBody(
1716 }1718 }
17171719
1718 // This job depends on any resolve_type_fully jobs queued up before it.1720 // This job depends on any resolve_type_fully jobs queued up before it.
1721 zcu.codegen_prog_node.increaseEstimatedTotalItems(1);
1722 comp.link_prog_node.increaseEstimatedTotalItems(1);
1719 try comp.queueJob(.{ .codegen_func = .{1723 try comp.queueJob(.{ .codegen_func = .{
1720 .func = func_index,1724 .func = func_index,
1721 .air = air,1725 .air = air,
...@@ -1724,87 +1728,6 @@ fn analyzeFuncBody(...@@ -1724,87 +1728,6 @@ fn analyzeFuncBody(
1724 return .{ .ies_outdated = ies_outdated };1728 return .{ .ies_outdated = ies_outdated };
1725}1729}
17261730
1727/// Takes ownership of `air`, even on error.
1728/// If any types referenced by `air` are unresolved, marks the codegen as failed.
1729pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) Allocator.Error!void {
1730 const zcu = pt.zcu;
1731 const gpa = zcu.gpa;
1732 const ip = &zcu.intern_pool;
1733 const comp = zcu.comp;
1734
1735 const func = zcu.funcInfo(func_index);
1736 const nav_index = func.owner_nav;
1737 const nav = ip.getNav(nav_index);
1738
1739 const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(ip), 0);
1740 defer codegen_prog_node.end();
1741
1742 if (!air.typesFullyResolved(zcu)) {
1743 // A type we depend on failed to resolve. This is a transitive failure.
1744 // Correcting this failure will involve changing a type this function
1745 // depends on, hence triggering re-analysis of this function, so this
1746 // interacts correctly with incremental compilation.
1747 return;
1748 }
1749
1750 legalize: {
1751 try air.legalize(pt, @import("../codegen.zig").legalizeFeatures(pt, nav_index) orelse break :legalize);
1752 }
1753
1754 var liveness = try Air.Liveness.analyze(zcu, air.*, ip);
1755 defer liveness.deinit(gpa);
1756
1757 if (build_options.enable_debug_extensions and comp.verbose_air) {
1758 std.debug.print("# Begin Function AIR: {}:\n", .{nav.fqn.fmt(ip)});
1759 air.dump(pt, liveness);
1760 std.debug.print("# End Function AIR: {}\n\n", .{nav.fqn.fmt(ip)});
1761 }
1762
1763 if (std.debug.runtime_safety) {
1764 var verify: Air.Liveness.Verify = .{
1765 .gpa = gpa,
1766 .zcu = zcu,
1767 .air = air.*,
1768 .liveness = liveness,
1769 .intern_pool = ip,
1770 };
1771 defer verify.deinit();
1772
1773 verify.verify() catch |err| switch (err) {
1774 error.OutOfMemory => return error.OutOfMemory,
1775 else => {
1776 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
1777 gpa,
1778 zcu.navSrcLoc(nav_index),
1779 "invalid liveness: {s}",
1780 .{@errorName(err)},
1781 ));
1782 return;
1783 },
1784 };
1785 }
1786
1787 if (comp.bin_file) |lf| {
1788 lf.updateFunc(pt, func_index, air.*, liveness) catch |err| switch (err) {
1789 error.OutOfMemory => return error.OutOfMemory,
1790 error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)),
1791 error.Overflow, error.RelocationNotByteAligned => {
1792 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
1793 gpa,
1794 zcu.navSrcLoc(nav_index),
1795 "unable to codegen: {s}",
1796 .{@errorName(err)},
1797 ));
1798 // Not a retryable failure.
1799 },
1800 };
1801 } else if (zcu.llvm_object) |llvm_object| {
1802 llvm_object.updateFunc(pt, func_index, air.*, liveness) catch |err| switch (err) {
1803 error.OutOfMemory => return error.OutOfMemory,
1804 };
1805 }
1806}
1807
1808pub fn semaMod(pt: Zcu.PerThread, mod: *Module) !void {1731pub fn semaMod(pt: Zcu.PerThread, mod: *Module) !void {
1809 dev.check(.sema);1732 dev.check(.sema);
1810 const file_index = pt.zcu.module_roots.get(mod).?.unwrap().?;1733 const file_index = pt.zcu.module_roots.get(mod).?.unwrap().?;
...@@ -1867,7 +1790,7 @@ fn createFileRootStruct(...@@ -1867,7 +1790,7 @@ fn createFileRootStruct(
1867 };1790 };
1868 errdefer wip_ty.cancel(ip, pt.tid);1791 errdefer wip_ty.cancel(ip, pt.tid);
18691792
1870 wip_ty.setName(ip, try file.internFullyQualifiedName(pt));1793 wip_ty.setName(ip, try file.internFullyQualifiedName(pt), .none);
1871 ip.namespacePtr(namespace_index).owner_type = wip_ty.index;1794 ip.namespacePtr(namespace_index).owner_type = wip_ty.index;
18721795
1873 if (zcu.comp.incremental) {1796 if (zcu.comp.incremental) {
...@@ -1877,10 +1800,10 @@ fn createFileRootStruct(...@@ -1877,10 +1800,10 @@ fn createFileRootStruct(
1877 try pt.scanNamespace(namespace_index, decls);1800 try pt.scanNamespace(namespace_index, decls);
1878 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });1801 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
1879 codegen_type: {1802 codegen_type: {
1880 if (zcu.comp.config.use_llvm) break :codegen_type;
1881 if (file.mod.?.strip) break :codegen_type;1803 if (file.mod.?.strip) break :codegen_type;
1882 // This job depends on any resolve_type_fully jobs queued up before it.1804 // This job depends on any resolve_type_fully jobs queued up before it.
1883 try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index });1805 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
1806 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
1884 }1807 }
1885 zcu.setFileRootType(file_index, wip_ty.index);1808 zcu.setFileRootType(file_index, wip_ty.index);
1886 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);1809 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
...@@ -2574,7 +2497,7 @@ fn newEmbedFile(...@@ -2574,7 +2497,7 @@ fn newEmbedFile(
2574 cache: {2497 cache: {
2575 const whole = switch (zcu.comp.cache_use) {2498 const whole = switch (zcu.comp.cache_use) {
2576 .whole => |whole| whole,2499 .whole => |whole| whole,
2577 .incremental => break :cache,2500 .incremental, .none => break :cache,
2578 };2501 };
2579 const man = whole.cache_manifest orelse break :cache;2502 const man = whole.cache_manifest orelse break :cache;
2580 const ip_str = opt_ip_str orelse break :cache; // this will be a compile error2503 const ip_str = opt_ip_str orelse break :cache; // this will be a compile error
...@@ -2974,17 +2897,10 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE...@@ -2974,17 +2897,10 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
2974 runtime_params_len;2897 runtime_params_len;
29752898
2976 var runtime_param_index: usize = 0;2899 var runtime_param_index: usize = 0;
2977 for (fn_info.param_body[0..src_params_len]) |inst| {2900 for (fn_info.param_body[0..src_params_len], 0..) |inst, zir_param_index| {
2978 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);2901 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
2979 if (gop.found_existing) continue; // provided above by comptime arg2902 if (gop.found_existing) continue; // provided above by comptime arg
29802903
2981 const param_inst_info = sema.code.instructions.get(@intFromEnum(inst));
2982 const param_name: Zir.NullTerminatedString = switch (param_inst_info.tag) {
2983 .param_anytype => param_inst_info.data.str_tok.start,
2984 .param => sema.code.extraData(Zir.Inst.Param, param_inst_info.data.pl_tok.payload_index).data.name,
2985 else => unreachable,
2986 };
2987
2988 const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index];2904 const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index];
2989 runtime_param_index += 1;2905 runtime_param_index += 1;
29902906
...@@ -3004,10 +2920,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE...@@ -3004,10 +2920,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
3004 .tag = .arg,2920 .tag = .arg,
3005 .data = .{ .arg = .{2921 .data = .{ .arg = .{
3006 .ty = Air.internedToRef(param_ty),2922 .ty = Air.internedToRef(param_ty),
3007 .name = if (inner_block.ownerModule().strip)2923 .zir_param_index = @intCast(zir_param_index),
3008 .none
3009 else
3010 try sema.appendAirString(sema.code.nullTerminatedString(param_name)),
3011 } },2924 } },
3012 });2925 });
3013 }2926 }
...@@ -3189,7 +3102,9 @@ pub fn processExports(pt: Zcu.PerThread) !void {...@@ -3189,7 +3102,9 @@ pub fn processExports(pt: Zcu.PerThread) !void {
3189 // This export might already have been sent to the linker on a previous update, in which case we need to delete it.3102 // This export might already have been sent to the linker on a previous update, in which case we need to delete it.
3190 // The linker export API should be modified to eliminate this call. #236163103 // The linker export API should be modified to eliminate this call. #23616
3191 if (zcu.comp.bin_file) |lf| {3104 if (zcu.comp.bin_file) |lf| {
3192 lf.deleteExport(exp.exported, exp.opts.name);3105 if (zcu.llvm_object == null) {
3106 lf.deleteExport(exp.exported, exp.opts.name);
3107 }
3193 }3108 }
3194 continue;3109 continue;
3195 }3110 }
...@@ -3213,8 +3128,10 @@ pub fn processExports(pt: Zcu.PerThread) !void {...@@ -3213,8 +3128,10 @@ pub fn processExports(pt: Zcu.PerThread) !void {
3213 // This export might already have been sent to the linker on a previous update, in which case we need to delete it.3128 // This export might already have been sent to the linker on a previous update, in which case we need to delete it.
3214 // The linker export API should be modified to eliminate this loop. #236163129 // The linker export API should be modified to eliminate this loop. #23616
3215 if (zcu.comp.bin_file) |lf| {3130 if (zcu.comp.bin_file) |lf| {
3216 for (exports) |exp| {3131 if (zcu.llvm_object == null) {
3217 lf.deleteExport(exp.exported, exp.opts.name);3132 for (exports) |exp| {
3133 lf.deleteExport(exp.exported, exp.opts.name);
3134 }
3218 }3135 }
3219 }3136 }
3220 continue;3137 continue;
...@@ -3309,46 +3226,49 @@ fn processExportsInner(...@@ -3309,46 +3226,49 @@ fn processExportsInner(
3309 .uav => {},3226 .uav => {},
3310 }3227 }
33113228
3312 if (zcu.comp.bin_file) |lf| {3229 if (zcu.llvm_object) |llvm_object| {
3313 try zcu.handleUpdateExports(export_indices, lf.updateExports(pt, exported, export_indices));
3314 } else if (zcu.llvm_object) |llvm_object| {
3315 try zcu.handleUpdateExports(export_indices, llvm_object.updateExports(pt, exported, export_indices));3230 try zcu.handleUpdateExports(export_indices, llvm_object.updateExports(pt, exported, export_indices));
3231 } else if (zcu.comp.bin_file) |lf| {
3232 try zcu.handleUpdateExports(export_indices, lf.updateExports(pt, exported, export_indices));
3316 }3233 }
3317}3234}
33183235
3319pub fn populateTestFunctions(3236pub fn populateTestFunctions(pt: Zcu.PerThread) Allocator.Error!void {
3320 pt: Zcu.PerThread,
3321 main_progress_node: std.Progress.Node,
3322) Allocator.Error!void {
3323 const zcu = pt.zcu;3237 const zcu = pt.zcu;
3324 const gpa = zcu.gpa;3238 const gpa = zcu.gpa;
3325 const ip = &zcu.intern_pool;3239 const ip = &zcu.intern_pool;
3240
3241 // Our job is to correctly set the value of the `test_functions` declaration if it has been
3242 // analyzed and sent to codegen, It usually will have been, because the test runner will
3243 // reference it, and `std.builtin` shouldn't have type errors. However, if it hasn't been
3244 // analyzed, we will just terminate early, since clearly the test runner hasn't referenced
3245 // `test_functions` so there's no point populating it. More to the the point, we potentially
3246 // *can't* populate it without doing some type resolution, and... let's try to leave Sema in
3247 // the past here.
3248
3326 const builtin_mod = zcu.builtin_modules.get(zcu.root_mod.getBuiltinOptions(zcu.comp.config).hash()).?;3249 const builtin_mod = zcu.builtin_modules.get(zcu.root_mod.getBuiltinOptions(zcu.comp.config).hash()).?;
3327 const builtin_file_index = zcu.module_roots.get(builtin_mod).?.unwrap().?;3250 const builtin_file_index = zcu.module_roots.get(builtin_mod).?.unwrap().?;
3328 pt.ensureFileAnalyzed(builtin_file_index) catch |err| switch (err) {3251 const builtin_root_type = zcu.fileRootType(builtin_file_index);
3329 error.AnalysisFail => unreachable, // builtin module is generated so cannot be corrupt3252 if (builtin_root_type == .none) return; // `@import("builtin")` never analyzed
3330 error.OutOfMemory => |e| return e,3253 const builtin_namespace = Type.fromInterned(builtin_root_type).getNamespace(zcu).unwrap().?;
3331 };3254 // We know that the namespace has a `test_functions`...
3332 const builtin_root_type = Type.fromInterned(zcu.fileRootType(builtin_file_index));
3333 const builtin_namespace = builtin_root_type.getNamespace(zcu).unwrap().?;
3334 const nav_index = zcu.namespacePtr(builtin_namespace).pub_decls.getKeyAdapted(3255 const nav_index = zcu.namespacePtr(builtin_namespace).pub_decls.getKeyAdapted(
3335 try ip.getOrPutString(gpa, pt.tid, "test_functions", .no_embedded_nulls),3256 try ip.getOrPutString(gpa, pt.tid, "test_functions", .no_embedded_nulls),
3336 Zcu.Namespace.NameAdapter{ .zcu = zcu },3257 Zcu.Namespace.NameAdapter{ .zcu = zcu },
3337 ).?;3258 ).?;
3259 // ...but it might not be populated, so let's check that!
3260 if (zcu.failed_analysis.contains(.wrap(.{ .nav_val = nav_index })) or
3261 zcu.transitive_failed_analysis.contains(.wrap(.{ .nav_val = nav_index })) or
3262 ip.getNav(nav_index).status != .fully_resolved)
3338 {3263 {
3339 // We have to call `ensureNavValUpToDate` here in case `builtin.test_functions`3264 // The value of `builtin.test_functions` was either never referenced, or failed analysis.
3340 // was not referenced by start code.3265 // Either way, we don't need to do anything.
3341 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);3266 return;
3342 defer {
3343 zcu.sema_prog_node.end();
3344 zcu.sema_prog_node = std.Progress.Node.none;
3345 }
3346 pt.ensureNavValUpToDate(nav_index) catch |err| switch (err) {
3347 error.AnalysisFail => return,
3348 error.OutOfMemory => return error.OutOfMemory,
3349 };
3350 }3267 }
33513268
3269 // Okay, `builtin.test_functions` is (potentially) referenced and valid. Our job now is to swap
3270 // its placeholder `&.{}` value for the actual list of all test functions.
3271
3352 const test_fns_val = zcu.navValue(nav_index);3272 const test_fns_val = zcu.navValue(nav_index);
3353 const test_fn_ty = test_fns_val.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu);3273 const test_fn_ty = test_fns_val.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu);
33543274
...@@ -3450,81 +3370,8 @@ pub fn populateTestFunctions(...@@ -3450,81 +3370,8 @@ pub fn populateTestFunctions(
3450 } });3370 } });
3451 ip.mutateVarInit(test_fns_val.toIntern(), new_init);3371 ip.mutateVarInit(test_fns_val.toIntern(), new_init);
3452 }3372 }
3453 {3373 // The linker thread is not running, so we actually need to dispatch this task directly.
3454 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);3374 @import("../link.zig").linkTestFunctionsNav(pt, nav_index);
3455 defer {
3456 zcu.codegen_prog_node.end();
3457 zcu.codegen_prog_node = std.Progress.Node.none;
3458 }
3459
3460 try pt.linkerUpdateNav(nav_index);
3461 }
3462}
3463
3464pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{OutOfMemory}!void {
3465 const zcu = pt.zcu;
3466 const comp = zcu.comp;
3467 const gpa = zcu.gpa;
3468 const ip = &zcu.intern_pool;
3469
3470 const nav = zcu.intern_pool.getNav(nav_index);
3471 const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(ip), 0);
3472 defer codegen_prog_node.end();
3473
3474 if (!Air.valFullyResolved(zcu.navValue(nav_index), zcu)) {
3475 // The value of this nav failed to resolve. This is a transitive failure.
3476 // TODO: do we need to mark this failure anywhere? I don't think so, since compilation
3477 // will fail due to the type error anyway.
3478 } else if (comp.bin_file) |lf| {
3479 lf.updateNav(pt, nav_index) catch |err| switch (err) {
3480 error.OutOfMemory => return error.OutOfMemory,
3481 error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)),
3482 error.Overflow, error.RelocationNotByteAligned => {
3483 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
3484 gpa,
3485 zcu.navSrcLoc(nav_index),
3486 "unable to codegen: {s}",
3487 .{@errorName(err)},
3488 ));
3489 // Not a retryable failure.
3490 },
3491 };
3492 } else if (zcu.llvm_object) |llvm_object| {
3493 llvm_object.updateNav(pt, nav_index) catch |err| switch (err) {
3494 error.OutOfMemory => return error.OutOfMemory,
3495 };
3496 }
3497}
3498
3499pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) error{OutOfMemory}!void {
3500 const zcu = pt.zcu;
3501 const gpa = zcu.gpa;
3502 const comp = zcu.comp;
3503 const ip = &zcu.intern_pool;
3504
3505 const codegen_prog_node = zcu.codegen_prog_node.start(Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), 0);
3506 defer codegen_prog_node.end();
3507
3508 if (zcu.failed_types.fetchSwapRemove(ty)) |*entry| entry.value.deinit(gpa);
3509
3510 if (!Air.typeFullyResolved(Type.fromInterned(ty), zcu)) {
3511 // This type failed to resolve. This is a transitive failure.
3512 return;
3513 }
3514
3515 if (comp.bin_file) |lf| lf.updateContainerType(pt, ty) catch |err| switch (err) {
3516 error.OutOfMemory => return error.OutOfMemory,
3517 error.TypeFailureReported => assert(zcu.failed_types.contains(ty)),
3518 };
3519}
3520
3521pub fn linkerUpdateLineNumber(pt: Zcu.PerThread, ti: InternPool.TrackedInst.Index) !void {
3522 if (pt.zcu.comp.bin_file) |lf| {
3523 lf.updateLineNumber(pt, ti) catch |err| switch (err) {
3524 error.OutOfMemory => return error.OutOfMemory,
3525 else => |e| log.err("update line number failed: {s}", .{@errorName(e)}),
3526 };
3527 }
3528}3375}
35293376
3530/// Stores an error in `pt.zcu.failed_files` for this file, and sets the file3377/// Stores an error in `pt.zcu.failed_files` for this file, and sets the file
...@@ -3984,7 +3831,8 @@ pub fn getExtern(pt: Zcu.PerThread, key: InternPool.Key.Extern) Allocator.Error!...@@ -3984,7 +3831,8 @@ pub fn getExtern(pt: Zcu.PerThread, key: InternPool.Key.Extern) Allocator.Error!
3984 const result = try pt.zcu.intern_pool.getExtern(pt.zcu.gpa, pt.tid, key);3831 const result = try pt.zcu.intern_pool.getExtern(pt.zcu.gpa, pt.tid, key);
3985 if (result.new_nav.unwrap()) |nav| {3832 if (result.new_nav.unwrap()) |nav| {
3986 // This job depends on any resolve_type_fully jobs queued up before it.3833 // This job depends on any resolve_type_fully jobs queued up before it.
3987 try pt.zcu.comp.queueJob(.{ .codegen_nav = nav });3834 pt.zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
3835 try pt.zcu.comp.queueJob(.{ .link_nav = nav });
3988 if (pt.zcu.comp.debugIncremental()) try pt.zcu.incremental_debug_state.newNav(pt.zcu, nav);3836 if (pt.zcu.comp.debugIncremental()) try pt.zcu.incremental_debug_state.newNav(pt.zcu, nav);
3989 }3837 }
3990 return result.index;3838 return result.index;
...@@ -4122,17 +3970,17 @@ fn recreateStructType(...@@ -4122,17 +3970,17 @@ fn recreateStructType(
4122 };3970 };
4123 errdefer wip_ty.cancel(ip, pt.tid);3971 errdefer wip_ty.cancel(ip, pt.tid);
41243972
4125 wip_ty.setName(ip, struct_obj.name);3973 wip_ty.setName(ip, struct_obj.name, struct_obj.name_nav);
4126 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = key.zir_index });3974 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = key.zir_index });
4127 zcu.namespacePtr(struct_obj.namespace).owner_type = wip_ty.index;3975 zcu.namespacePtr(struct_obj.namespace).owner_type = wip_ty.index;
4128 // No need to re-scan the namespace -- `zirStructDecl` will ultimately do that if the type is still alive.3976 // No need to re-scan the namespace -- `zirStructDecl` will ultimately do that if the type is still alive.
4129 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });3977 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
41303978
4131 codegen_type: {3979 codegen_type: {
4132 if (zcu.comp.config.use_llvm) break :codegen_type;
4133 if (file.mod.?.strip) break :codegen_type;3980 if (file.mod.?.strip) break :codegen_type;
4134 // This job depends on any resolve_type_fully jobs queued up before it.3981 // This job depends on any resolve_type_fully jobs queued up before it.
4135 try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index });3982 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
3983 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
4136 }3984 }
41373985
4138 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);3986 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
...@@ -4215,17 +4063,17 @@ fn recreateUnionType(...@@ -4215,17 +4063,17 @@ fn recreateUnionType(
4215 };4063 };
4216 errdefer wip_ty.cancel(ip, pt.tid);4064 errdefer wip_ty.cancel(ip, pt.tid);
42174065
4218 wip_ty.setName(ip, union_obj.name);4066 wip_ty.setName(ip, union_obj.name, union_obj.name_nav);
4219 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = key.zir_index });4067 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = key.zir_index });
4220 zcu.namespacePtr(namespace_index).owner_type = wip_ty.index;4068 zcu.namespacePtr(namespace_index).owner_type = wip_ty.index;
4221 // No need to re-scan the namespace -- `zirUnionDecl` will ultimately do that if the type is still alive.4069 // No need to re-scan the namespace -- `zirUnionDecl` will ultimately do that if the type is still alive.
4222 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });4070 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
42234071
4224 codegen_type: {4072 codegen_type: {
4225 if (zcu.comp.config.use_llvm) break :codegen_type;
4226 if (file.mod.?.strip) break :codegen_type;4073 if (file.mod.?.strip) break :codegen_type;
4227 // This job depends on any resolve_type_fully jobs queued up before it.4074 // This job depends on any resolve_type_fully jobs queued up before it.
4228 try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index });4075 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
4076 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
4229 }4077 }
42304078
4231 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);4079 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
...@@ -4325,7 +4173,7 @@ fn recreateEnumType(...@@ -4325,7 +4173,7 @@ fn recreateEnumType(
4325 var done = true;4173 var done = true;
4326 errdefer if (!done) wip_ty.cancel(ip, pt.tid);4174 errdefer if (!done) wip_ty.cancel(ip, pt.tid);
43274175
4328 wip_ty.setName(ip, enum_obj.name);4176 wip_ty.setName(ip, enum_obj.name, enum_obj.name_nav);
43294177
4330 zcu.namespacePtr(namespace_index).owner_type = wip_ty.index;4178 zcu.namespacePtr(namespace_index).owner_type = wip_ty.index;
4331 // No need to re-scan the namespace -- `zirEnumDecl` will ultimately do that if the type is still alive.4179 // No need to re-scan the namespace -- `zirEnumDecl` will ultimately do that if the type is still alive.
...@@ -4518,3 +4366,128 @@ pub fn addDependency(pt: Zcu.PerThread, unit: AnalUnit, dependee: InternPool.Dep...@@ -4518,3 +4366,128 @@ pub fn addDependency(pt: Zcu.PerThread, unit: AnalUnit, dependee: InternPool.Dep
4518 try info.deps.append(gpa, dependee);4366 try info.deps.append(gpa, dependee);
4519 }4367 }
4520}4368}
4369
4370/// Performs code generation, which comes after `Sema` but before `link` in the pipeline.
4371/// This part of the pipeline is self-contained/"pure", so can be run in parallel with most
4372/// other code. This function is currently run either on the main thread, or on a separate
4373/// codegen thread, depending on whether the backend supports `Zcu.Feature.separate_thread`.
4374pub fn runCodegen(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air, out: *@import("../link.zig").ZcuTask.LinkFunc.SharedMir) void {
4375 const zcu = pt.zcu;
4376 if (runCodegenInner(pt, func_index, air)) |mir| {
4377 out.value = mir;
4378 out.status.store(.ready, .release);
4379 } else |err| switch (err) {
4380 error.OutOfMemory => {
4381 zcu.comp.setAllocFailure();
4382 out.status.store(.failed, .monotonic);
4383 },
4384 error.CodegenFail => {
4385 zcu.assertCodegenFailed(zcu.funcInfo(func_index).owner_nav);
4386 out.status.store(.failed, .monotonic);
4387 },
4388 error.NoLinkFile => {
4389 assert(zcu.comp.bin_file == null);
4390 out.status.store(.failed, .monotonic);
4391 },
4392 error.BackendDoesNotProduceMir => {
4393 const backend = target_util.zigBackend(zcu.root_mod.resolved_target.result, zcu.comp.config.use_llvm);
4394 switch (backend) {
4395 else => unreachable, // assertion failure
4396 .stage2_spirv64,
4397 .stage2_llvm,
4398 => {},
4399 }
4400 out.status.store(.failed, .monotonic);
4401 },
4402 }
4403 zcu.comp.link_task_queue.mirReady(zcu.comp, out);
4404 if (zcu.pending_codegen_jobs.rmw(.Sub, 1, .monotonic) == 1) {
4405 // Decremented to 0, so all done.
4406 zcu.codegen_prog_node.end();
4407 zcu.codegen_prog_node = .none;
4408 }
4409}
4410fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) error{
4411 OutOfMemory,
4412 CodegenFail,
4413 NoLinkFile,
4414 BackendDoesNotProduceMir,
4415}!codegen.AnyMir {
4416 const zcu = pt.zcu;
4417 const gpa = zcu.gpa;
4418 const ip = &zcu.intern_pool;
4419 const comp = zcu.comp;
4420
4421 const nav = zcu.funcInfo(func_index).owner_nav;
4422 const fqn = ip.getNav(nav).fqn;
4423
4424 const codegen_prog_node = zcu.codegen_prog_node.start(fqn.toSlice(ip), 0);
4425 defer codegen_prog_node.end();
4426
4427 if (codegen.legalizeFeatures(pt, nav)) |features| {
4428 try air.legalize(pt, features);
4429 }
4430
4431 var liveness: Air.Liveness = try .analyze(zcu, air.*, ip);
4432 defer liveness.deinit(gpa);
4433
4434 if (build_options.enable_debug_extensions and comp.verbose_air) {
4435 std.debug.lockStdErr();
4436 defer std.debug.unlockStdErr();
4437 const stderr = std.io.getStdErr().writer();
4438 stderr.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)}) catch {};
4439 air.write(stderr, pt, liveness);
4440 stderr.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)}) catch {};
4441 }
4442
4443 if (std.debug.runtime_safety) {
4444 var verify: Air.Liveness.Verify = .{
4445 .gpa = gpa,
4446 .zcu = zcu,
4447 .air = air.*,
4448 .liveness = liveness,
4449 .intern_pool = ip,
4450 };
4451 defer verify.deinit();
4452
4453 verify.verify() catch |err| switch (err) {
4454 error.OutOfMemory => return error.OutOfMemory,
4455 else => return zcu.codegenFail(nav, "invalid liveness: {s}", .{@errorName(err)}),
4456 };
4457 }
4458
4459 // The LLVM backend is special, because we only need to do codegen. There is no equivalent to the
4460 // "emit" step because LLVM does not support incremental linking. Our linker (LLD or self-hosted)
4461 // will just see the ZCU object file which LLVM ultimately emits.
4462 if (zcu.llvm_object) |llvm_object| {
4463 assert(pt.tid == .main); // LLVM has a lot of shared state
4464 try llvm_object.updateFunc(pt, func_index, air, &liveness);
4465 return error.BackendDoesNotProduceMir;
4466 }
4467
4468 const lf = comp.bin_file orelse return error.NoLinkFile;
4469
4470 // TODO: self-hosted codegen should always have a type of MIR; codegen should produce that MIR,
4471 // and the linker should consume it. However, our SPIR-V backend is currently tightly coupled
4472 // with our SPIR-V linker, so needs to work more like the LLVM backend. This should be fixed to
4473 // unblock threaded codegen for SPIR-V.
4474 if (lf.cast(.spirv)) |spirv_file| {
4475 assert(pt.tid == .main); // SPIR-V has a lot of shared state
4476 spirv_file.object.updateFunc(pt, func_index, air, &liveness) catch |err| {
4477 switch (err) {
4478 error.OutOfMemory => comp.link_diags.setAllocFailure(),
4479 }
4480 return error.CodegenFail;
4481 };
4482 return error.BackendDoesNotProduceMir;
4483 }
4484
4485 return codegen.generateFunction(lf, pt, zcu.navSrcLoc(nav), func_index, air, &liveness) catch |err| switch (err) {
4486 error.OutOfMemory,
4487 error.CodegenFail,
4488 => |e| return e,
4489 error.Overflow,
4490 error.RelocationNotByteAligned,
4491 => return zcu.codegenFail(nav, "unable to codegen: {s}", .{@errorName(err)}),
4492 };
4493}
src/arch/aarch64/CodeGen.zig+32-39
...@@ -49,7 +49,6 @@ pt: Zcu.PerThread,...@@ -49,7 +49,6 @@ pt: Zcu.PerThread,
49air: Air,49air: Air,
50liveness: Air.Liveness,50liveness: Air.Liveness,
51bin_file: *link.File,51bin_file: *link.File,
52debug_output: link.File.DebugInfoOutput,
53target: *const std.Target,52target: *const std.Target,
54func_index: InternPool.Index,53func_index: InternPool.Index,
55owner_nav: InternPool.Nav.Index,54owner_nav: InternPool.Nav.Index,
...@@ -185,6 +184,9 @@ const DbgInfoReloc = struct {...@@ -185,6 +184,9 @@ const DbgInfoReloc = struct {
185 }184 }
186185
187 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !void {186 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
187 // TODO: Add a pseudo-instruction or something to defer this work until Emit.
188 // We aren't allowed to interact with linker state here.
189 if (true) return;
188 switch (function.debug_output) {190 switch (function.debug_output) {
189 .dwarf => |dw| {191 .dwarf => |dw| {
190 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {192 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
...@@ -213,6 +215,9 @@ const DbgInfoReloc = struct {...@@ -213,6 +215,9 @@ const DbgInfoReloc = struct {
213 }215 }
214216
215 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {217 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
218 // TODO: Add a pseudo-instruction or something to defer this work until Emit.
219 // We aren't allowed to interact with linker state here.
220 if (true) return;
216 switch (function.debug_output) {221 switch (function.debug_output) {
217 .dwarf => |dwarf| {222 .dwarf => |dwarf| {
218 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {223 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
...@@ -326,11 +331,9 @@ pub fn generate(...@@ -326,11 +331,9 @@ pub fn generate(
326 pt: Zcu.PerThread,331 pt: Zcu.PerThread,
327 src_loc: Zcu.LazySrcLoc,332 src_loc: Zcu.LazySrcLoc,
328 func_index: InternPool.Index,333 func_index: InternPool.Index,
329 air: Air,334 air: *const Air,
330 liveness: Air.Liveness,335 liveness: *const Air.Liveness,
331 code: *std.ArrayListUnmanaged(u8),336) CodeGenError!Mir {
332 debug_output: link.File.DebugInfoOutput,
333) CodeGenError!void {
334 const zcu = pt.zcu;337 const zcu = pt.zcu;
335 const gpa = zcu.gpa;338 const gpa = zcu.gpa;
336 const func = zcu.funcInfo(func_index);339 const func = zcu.funcInfo(func_index);
...@@ -349,9 +352,8 @@ pub fn generate(...@@ -349,9 +352,8 @@ pub fn generate(
349 var function: Self = .{352 var function: Self = .{
350 .gpa = gpa,353 .gpa = gpa,
351 .pt = pt,354 .pt = pt,
352 .air = air,355 .air = air.*,
353 .liveness = liveness,356 .liveness = liveness.*,
354 .debug_output = debug_output,
355 .target = target,357 .target = target,
356 .bin_file = lf,358 .bin_file = lf,
357 .func_index = func_index,359 .func_index = func_index,
...@@ -395,29 +397,13 @@ pub fn generate(...@@ -395,29 +397,13 @@ pub fn generate(
395397
396 var mir: Mir = .{398 var mir: Mir = .{
397 .instructions = function.mir_instructions.toOwnedSlice(),399 .instructions = function.mir_instructions.toOwnedSlice(),
398 .extra = try function.mir_extra.toOwnedSlice(gpa),400 .extra = &.{}, // fallible, so assign after errdefer
399 };401 .max_end_stack = function.max_end_stack,
400 defer mir.deinit(gpa);
401
402 var emit: Emit = .{
403 .mir = mir,
404 .bin_file = lf,
405 .debug_output = debug_output,
406 .target = target,
407 .src_loc = src_loc,
408 .code = code,
409 .prev_di_pc = 0,
410 .prev_di_line = func.lbrace_line,
411 .prev_di_column = func.lbrace_column,
412 .stack_size = function.max_end_stack,
413 .saved_regs_stack_space = function.saved_regs_stack_space,402 .saved_regs_stack_space = function.saved_regs_stack_space,
414 };403 };
415 defer emit.deinit();404 errdefer mir.deinit(gpa);
416405 mir.extra = try function.mir_extra.toOwnedSlice(gpa);
417 emit.emitMir() catch |err| switch (err) {406 return mir;
418 error.EmitFail => return function.failMsg(emit.err_msg.?),
419 else => |e| return e,
420 };
421}407}
422408
423fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {409fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
...@@ -4222,15 +4208,22 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {...@@ -4222,15 +4208,22 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {
4222 while (self.args[arg_index] == .none) arg_index += 1;4208 while (self.args[arg_index] == .none) arg_index += 1;
4223 self.arg_index = arg_index + 1;4209 self.arg_index = arg_index + 1;
42244210
4225 const ty = self.typeOfIndex(inst);4211 const zcu = self.pt.zcu;
4226 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];4212 const func_zir = zcu.funcInfo(self.func_index).zir_body_inst.resolveFull(&zcu.intern_pool).?;
4227 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;4213 const file = zcu.fileByIndex(func_zir.file);
4228 if (name != .none) try self.dbg_info_relocs.append(self.gpa, .{4214 if (!file.mod.?.strip) {
4229 .tag = tag,4215 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
4230 .ty = ty,4216 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
4231 .name = name.toSlice(self.air),4217 const ty = self.typeOfIndex(inst);
4232 .mcv = self.args[arg_index],4218 const zir = &file.zir.?;
4233 });4219 const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
4220 try self.dbg_info_relocs.append(self.gpa, .{
4221 .tag = tag,
4222 .ty = ty,
4223 .name = name,
4224 .mcv = self.args[arg_index],
4225 });
4226 }
42344227
4235 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];4228 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
4236 return self.finishAir(inst, result, .{ .none, .none, .none });4229 return self.finishAir(inst, result, .{ .none, .none, .none });
src/arch/aarch64/Mir.zig+41
...@@ -13,6 +13,14 @@ const assert = std.debug.assert;...@@ -13,6 +13,14 @@ const assert = std.debug.assert;
1313
14const bits = @import("bits.zig");14const bits = @import("bits.zig");
15const Register = bits.Register;15const Register = bits.Register;
16const InternPool = @import("../../InternPool.zig");
17const Emit = @import("Emit.zig");
18const codegen = @import("../../codegen.zig");
19const link = @import("../../link.zig");
20const Zcu = @import("../../Zcu.zig");
21
22max_end_stack: u32,
23saved_regs_stack_space: u32,
1624
17instructions: std.MultiArrayList(Inst).Slice,25instructions: std.MultiArrayList(Inst).Slice,
18/// The meaning of this data is determined by `Inst.Tag` value.26/// The meaning of this data is determined by `Inst.Tag` value.
...@@ -498,6 +506,39 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {...@@ -498,6 +506,39 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
498 mir.* = undefined;506 mir.* = undefined;
499}507}
500508
509pub fn emit(
510 mir: Mir,
511 lf: *link.File,
512 pt: Zcu.PerThread,
513 src_loc: Zcu.LazySrcLoc,
514 func_index: InternPool.Index,
515 code: *std.ArrayListUnmanaged(u8),
516 debug_output: link.File.DebugInfoOutput,
517) codegen.CodeGenError!void {
518 const zcu = pt.zcu;
519 const func = zcu.funcInfo(func_index);
520 const nav = func.owner_nav;
521 const mod = zcu.navFileScope(nav).mod.?;
522 var e: Emit = .{
523 .mir = mir,
524 .bin_file = lf,
525 .debug_output = debug_output,
526 .target = &mod.resolved_target.result,
527 .src_loc = src_loc,
528 .code = code,
529 .prev_di_pc = 0,
530 .prev_di_line = func.lbrace_line,
531 .prev_di_column = func.lbrace_column,
532 .stack_size = mir.max_end_stack,
533 .saved_regs_stack_space = mir.saved_regs_stack_space,
534 };
535 defer e.deinit();
536 e.emitMir() catch |err| switch (err) {
537 error.EmitFail => return zcu.codegenFailMsg(nav, e.err_msg.?),
538 else => |e1| return e1,
539 };
540}
541
501/// Returns the requested data, as well as the new index which is at the start of the542/// Returns the requested data, as well as the new index which is at the start of the
502/// trailers for the object.543/// trailers for the object.
503pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } {544pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } {
src/arch/arm/CodeGen.zig+33-41
...@@ -50,7 +50,6 @@ pt: Zcu.PerThread,...@@ -50,7 +50,6 @@ pt: Zcu.PerThread,
50air: Air,50air: Air,
51liveness: Air.Liveness,51liveness: Air.Liveness,
52bin_file: *link.File,52bin_file: *link.File,
53debug_output: link.File.DebugInfoOutput,
54target: *const std.Target,53target: *const std.Target,
55func_index: InternPool.Index,54func_index: InternPool.Index,
56err_msg: ?*ErrorMsg,55err_msg: ?*ErrorMsg,
...@@ -264,6 +263,9 @@ const DbgInfoReloc = struct {...@@ -264,6 +263,9 @@ const DbgInfoReloc = struct {
264 }263 }
265264
266 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !void {265 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
266 // TODO: Add a pseudo-instruction or something to defer this work until Emit.
267 // We aren't allowed to interact with linker state here.
268 if (true) return;
267 switch (function.debug_output) {269 switch (function.debug_output) {
268 .dwarf => |dw| {270 .dwarf => |dw| {
269 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {271 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
...@@ -292,6 +294,9 @@ const DbgInfoReloc = struct {...@@ -292,6 +294,9 @@ const DbgInfoReloc = struct {
292 }294 }
293295
294 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {296 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
297 // TODO: Add a pseudo-instruction or something to defer this work until Emit.
298 // We aren't allowed to interact with linker state here.
299 if (true) return;
295 switch (function.debug_output) {300 switch (function.debug_output) {
296 .dwarf => |dw| {301 .dwarf => |dw| {
297 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {302 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
...@@ -335,11 +340,9 @@ pub fn generate(...@@ -335,11 +340,9 @@ pub fn generate(
335 pt: Zcu.PerThread,340 pt: Zcu.PerThread,
336 src_loc: Zcu.LazySrcLoc,341 src_loc: Zcu.LazySrcLoc,
337 func_index: InternPool.Index,342 func_index: InternPool.Index,
338 air: Air,343 air: *const Air,
339 liveness: Air.Liveness,344 liveness: *const Air.Liveness,
340 code: *std.ArrayListUnmanaged(u8),345) CodeGenError!Mir {
341 debug_output: link.File.DebugInfoOutput,
342) CodeGenError!void {
343 const zcu = pt.zcu;346 const zcu = pt.zcu;
344 const gpa = zcu.gpa;347 const gpa = zcu.gpa;
345 const func = zcu.funcInfo(func_index);348 const func = zcu.funcInfo(func_index);
...@@ -358,11 +361,10 @@ pub fn generate(...@@ -358,11 +361,10 @@ pub fn generate(
358 var function: Self = .{361 var function: Self = .{
359 .gpa = gpa,362 .gpa = gpa,
360 .pt = pt,363 .pt = pt,
361 .air = air,364 .air = air.*,
362 .liveness = liveness,365 .liveness = liveness.*,
363 .target = target,366 .target = target,
364 .bin_file = lf,367 .bin_file = lf,
365 .debug_output = debug_output,
366 .func_index = func_index,368 .func_index = func_index,
367 .err_msg = null,369 .err_msg = null,
368 .args = undefined, // populated after `resolveCallingConventionValues`370 .args = undefined, // populated after `resolveCallingConventionValues`
...@@ -402,31 +404,15 @@ pub fn generate(...@@ -402,31 +404,15 @@ pub fn generate(
402 return function.fail("failed to generate debug info: {s}", .{@errorName(err)});404 return function.fail("failed to generate debug info: {s}", .{@errorName(err)});
403 }405 }
404406
405 var mir = Mir{407 var mir: Mir = .{
406 .instructions = function.mir_instructions.toOwnedSlice(),408 .instructions = function.mir_instructions.toOwnedSlice(),
407 .extra = try function.mir_extra.toOwnedSlice(gpa),409 .extra = &.{}, // fallible, so assign after errdefer
408 };410 .max_end_stack = function.max_end_stack,
409 defer mir.deinit(gpa);
410
411 var emit = Emit{
412 .mir = mir,
413 .bin_file = lf,
414 .debug_output = debug_output,
415 .target = target,
416 .src_loc = src_loc,
417 .code = code,
418 .prev_di_pc = 0,
419 .prev_di_line = func.lbrace_line,
420 .prev_di_column = func.lbrace_column,
421 .stack_size = function.max_end_stack,
422 .saved_regs_stack_space = function.saved_regs_stack_space,411 .saved_regs_stack_space = function.saved_regs_stack_space,
423 };412 };
424 defer emit.deinit();413 errdefer mir.deinit(gpa);
425414 mir.extra = try function.mir_extra.toOwnedSlice(gpa);
426 emit.emitMir() catch |err| switch (err) {415 return mir;
427 error.EmitFail => return function.failMsg(emit.err_msg.?),
428 else => |e| return e,
429 };
430}416}
431417
432fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {418fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
...@@ -4205,16 +4191,22 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -4205,16 +4191,22 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
4205 while (self.args[arg_index] == .none) arg_index += 1;4191 while (self.args[arg_index] == .none) arg_index += 1;
4206 self.arg_index = arg_index + 1;4192 self.arg_index = arg_index + 1;
42074193
4208 const ty = self.typeOfIndex(inst);4194 const zcu = self.pt.zcu;
4209 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];4195 const func_zir = zcu.funcInfo(self.func_index).zir_body_inst.resolveFull(&zcu.intern_pool).?;
42104196 const file = zcu.fileByIndex(func_zir.file);
4211 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;4197 if (!file.mod.?.strip) {
4212 if (name != .none) try self.dbg_info_relocs.append(self.gpa, .{4198 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
4213 .tag = tag,4199 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
4214 .ty = ty,4200 const ty = self.typeOfIndex(inst);
4215 .name = name.toSlice(self.air),4201 const zir = &file.zir.?;
4216 .mcv = self.args[arg_index],4202 const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
4217 });4203 try self.dbg_info_relocs.append(self.gpa, .{
4204 .tag = tag,
4205 .ty = ty,
4206 .name = name,
4207 .mcv = self.args[arg_index],
4208 });
4209 }
42184210
4219 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];4211 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
4220 return self.finishAir(inst, result, .{ .none, .none, .none });4212 return self.finishAir(inst, result, .{ .none, .none, .none });
src/arch/arm/Mir.zig+41
...@@ -13,6 +13,14 @@ const assert = std.debug.assert;...@@ -13,6 +13,14 @@ const assert = std.debug.assert;
1313
14const bits = @import("bits.zig");14const bits = @import("bits.zig");
15const Register = bits.Register;15const Register = bits.Register;
16const InternPool = @import("../../InternPool.zig");
17const Emit = @import("Emit.zig");
18const codegen = @import("../../codegen.zig");
19const link = @import("../../link.zig");
20const Zcu = @import("../../Zcu.zig");
21
22max_end_stack: u32,
23saved_regs_stack_space: u32,
1624
17instructions: std.MultiArrayList(Inst).Slice,25instructions: std.MultiArrayList(Inst).Slice,
18/// The meaning of this data is determined by `Inst.Tag` value.26/// The meaning of this data is determined by `Inst.Tag` value.
...@@ -278,6 +286,39 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {...@@ -278,6 +286,39 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
278 mir.* = undefined;286 mir.* = undefined;
279}287}
280288
289pub fn emit(
290 mir: Mir,
291 lf: *link.File,
292 pt: Zcu.PerThread,
293 src_loc: Zcu.LazySrcLoc,
294 func_index: InternPool.Index,
295 code: *std.ArrayListUnmanaged(u8),
296 debug_output: link.File.DebugInfoOutput,
297) codegen.CodeGenError!void {
298 const zcu = pt.zcu;
299 const func = zcu.funcInfo(func_index);
300 const nav = func.owner_nav;
301 const mod = zcu.navFileScope(nav).mod.?;
302 var e: Emit = .{
303 .mir = mir,
304 .bin_file = lf,
305 .debug_output = debug_output,
306 .target = &mod.resolved_target.result,
307 .src_loc = src_loc,
308 .code = code,
309 .prev_di_pc = 0,
310 .prev_di_line = func.lbrace_line,
311 .prev_di_column = func.lbrace_column,
312 .stack_size = mir.max_end_stack,
313 .saved_regs_stack_space = mir.saved_regs_stack_space,
314 };
315 defer e.deinit();
316 e.emitMir() catch |err| switch (err) {
317 error.EmitFail => return zcu.codegenFailMsg(nav, e.err_msg.?),
318 else => |e1| return e1,
319 };
320}
321
281/// Returns the requested data, as well as the new index which is at the start of the322/// Returns the requested data, as well as the new index which is at the start of the
282/// trailers for the object.323/// trailers for the object.
283pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } {324pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } {
src/arch/powerpc/CodeGen.zig+3-7
...@@ -19,19 +19,15 @@ pub fn generate(...@@ -19,19 +19,15 @@ pub fn generate(
19 pt: Zcu.PerThread,19 pt: Zcu.PerThread,
20 src_loc: Zcu.LazySrcLoc,20 src_loc: Zcu.LazySrcLoc,
21 func_index: InternPool.Index,21 func_index: InternPool.Index,
22 air: Air,22 air: *const Air,
23 liveness: Air.Liveness,23 liveness: *const Air.Liveness,
24 code: *std.ArrayListUnmanaged(u8),24) codegen.CodeGenError!noreturn {
25 debug_output: link.File.DebugInfoOutput,
26) codegen.CodeGenError!void {
27 _ = bin_file;25 _ = bin_file;
28 _ = pt;26 _ = pt;
29 _ = src_loc;27 _ = src_loc;
30 _ = func_index;28 _ = func_index;
31 _ = air;29 _ = air;
32 _ = liveness;30 _ = liveness;
33 _ = code;
34 _ = debug_output;
3531
36 unreachable;32 unreachable;
37}33}
src/arch/riscv64/CodeGen.zig+30-47
...@@ -68,9 +68,9 @@ gpa: Allocator,...@@ -68,9 +68,9 @@ gpa: Allocator,
6868
69mod: *Package.Module,69mod: *Package.Module,
70target: *const std.Target,70target: *const std.Target,
71debug_output: link.File.DebugInfoOutput,
72args: []MCValue,71args: []MCValue,
73ret_mcv: InstTracking,72ret_mcv: InstTracking,
73func_index: InternPool.Index,
74fn_type: Type,74fn_type: Type,
75arg_index: usize,75arg_index: usize,
76src_loc: Zcu.LazySrcLoc,76src_loc: Zcu.LazySrcLoc,
...@@ -746,13 +746,10 @@ pub fn generate(...@@ -746,13 +746,10 @@ pub fn generate(
746 pt: Zcu.PerThread,746 pt: Zcu.PerThread,
747 src_loc: Zcu.LazySrcLoc,747 src_loc: Zcu.LazySrcLoc,
748 func_index: InternPool.Index,748 func_index: InternPool.Index,
749 air: Air,749 air: *const Air,
750 liveness: Air.Liveness,750 liveness: *const Air.Liveness,
751 code: *std.ArrayListUnmanaged(u8),751) CodeGenError!Mir {
752 debug_output: link.File.DebugInfoOutput,
753) CodeGenError!void {
754 const zcu = pt.zcu;752 const zcu = pt.zcu;
755 const comp = zcu.comp;
756 const gpa = zcu.gpa;753 const gpa = zcu.gpa;
757 const ip = &zcu.intern_pool;754 const ip = &zcu.intern_pool;
758 const func = zcu.funcInfo(func_index);755 const func = zcu.funcInfo(func_index);
...@@ -769,16 +766,16 @@ pub fn generate(...@@ -769,16 +766,16 @@ pub fn generate(
769766
770 var function: Func = .{767 var function: Func = .{
771 .gpa = gpa,768 .gpa = gpa,
772 .air = air,769 .air = air.*,
773 .pt = pt,770 .pt = pt,
774 .mod = mod,771 .mod = mod,
775 .bin_file = bin_file,772 .bin_file = bin_file,
776 .liveness = liveness,773 .liveness = liveness.*,
777 .target = &mod.resolved_target.result,774 .target = &mod.resolved_target.result,
778 .debug_output = debug_output,
779 .owner = .{ .nav_index = func.owner_nav },775 .owner = .{ .nav_index = func.owner_nav },
780 .args = undefined, // populated after `resolveCallingConventionValues`776 .args = undefined, // populated after `resolveCallingConventionValues`
781 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`777 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
778 .func_index = func_index,
782 .fn_type = fn_type,779 .fn_type = fn_type,
783 .arg_index = 0,780 .arg_index = 0,
784 .branch_stack = &branch_stack,781 .branch_stack = &branch_stack,
...@@ -855,33 +852,8 @@ pub fn generate(...@@ -855,33 +852,8 @@ pub fn generate(
855 .instructions = function.mir_instructions.toOwnedSlice(),852 .instructions = function.mir_instructions.toOwnedSlice(),
856 .frame_locs = function.frame_locs.toOwnedSlice(),853 .frame_locs = function.frame_locs.toOwnedSlice(),
857 };854 };
858 defer mir.deinit(gpa);855 errdefer mir.deinit(gpa);
859856 return mir;
860 var emit: Emit = .{
861 .lower = .{
862 .pt = pt,
863 .allocator = gpa,
864 .mir = mir,
865 .cc = fn_info.cc,
866 .src_loc = src_loc,
867 .output_mode = comp.config.output_mode,
868 .link_mode = comp.config.link_mode,
869 .pic = mod.pic,
870 },
871 .bin_file = bin_file,
872 .debug_output = debug_output,
873 .code = code,
874 .prev_di_pc = 0,
875 .prev_di_line = func.lbrace_line,
876 .prev_di_column = func.lbrace_column,
877 };
878 defer emit.deinit();
879
880 emit.emitMir() catch |err| switch (err) {
881 error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
882 error.InvalidInstruction => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}),
883 else => |e| return e,
884 };
885}857}
886858
887pub fn generateLazy(859pub fn generateLazy(
...@@ -904,10 +876,10 @@ pub fn generateLazy(...@@ -904,10 +876,10 @@ pub fn generateLazy(
904 .bin_file = bin_file,876 .bin_file = bin_file,
905 .liveness = undefined,877 .liveness = undefined,
906 .target = &mod.resolved_target.result,878 .target = &mod.resolved_target.result,
907 .debug_output = debug_output,
908 .owner = .{ .lazy_sym = lazy_sym },879 .owner = .{ .lazy_sym = lazy_sym },
909 .args = undefined, // populated after `resolveCallingConventionValues`880 .args = undefined, // populated after `resolveCallingConventionValues`
910 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`881 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
882 .func_index = undefined,
911 .fn_type = undefined,883 .fn_type = undefined,
912 .arg_index = 0,884 .arg_index = 0,
913 .branch_stack = undefined,885 .branch_stack = undefined,
...@@ -3631,9 +3603,7 @@ fn airRuntimeNavPtr(func: *Func, inst: Air.Inst.Index) !void {...@@ -3631,9 +3603,7 @@ fn airRuntimeNavPtr(func: *Func, inst: Air.Inst.Index) !void {
3631 const tlv_sym_index = if (func.bin_file.cast(.elf)) |elf_file| sym: {3603 const tlv_sym_index = if (func.bin_file.cast(.elf)) |elf_file| sym: {
3632 const zo = elf_file.zigObjectPtr().?;3604 const zo = elf_file.zigObjectPtr().?;
3633 if (nav.getExtern(ip)) |e| {3605 if (nav.getExtern(ip)) |e| {
3634 const sym = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), e.lib_name.toSlice(ip));3606 break :sym try elf_file.getGlobalSymbol(nav.name.toSlice(ip), e.lib_name.toSlice(ip));
3635 zo.symbol(sym).flags.is_extern_ptr = true;
3636 break :sym sym;
3637 }3607 }
3638 break :sym try zo.getOrCreateMetadataForNav(zcu, ty_nav.nav);3608 break :sym try zo.getOrCreateMetadataForNav(zcu, ty_nav.nav);
3639 } else return func.fail("TODO runtime_nav_ptr on {}", .{func.bin_file.tag});3609 } else return func.fail("TODO runtime_nav_ptr on {}", .{func.bin_file.tag});
...@@ -4755,16 +4725,17 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {...@@ -4755,16 +4725,17 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {
4755 return func.fail("TODO implement codegen airFieldParentPtr", .{});4725 return func.fail("TODO implement codegen airFieldParentPtr", .{});
4756}4726}
47574727
4758fn genArgDbgInfo(func: *const Func, inst: Air.Inst.Index, mcv: MCValue) InnerError!void {4728fn genArgDbgInfo(func: *const Func, name: []const u8, ty: Type, mcv: MCValue) InnerError!void {
4759 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;4729 assert(!func.mod.strip);
4760 const ty = arg.ty.toType();
4761 if (arg.name == .none) return;
47624730
4731 // TODO: Add a pseudo-instruction or something to defer this work until Emit.
4732 // We aren't allowed to interact with linker state here.
4733 if (true) return;
4763 switch (func.debug_output) {4734 switch (func.debug_output) {
4764 .dwarf => |dw| switch (mcv) {4735 .dwarf => |dw| switch (mcv) {
4765 .register => |reg| dw.genLocalDebugInfo(4736 .register => |reg| dw.genLocalDebugInfo(
4766 .local_arg,4737 .local_arg,
4767 arg.name.toSlice(func.air),4738 name,
4768 ty,4739 ty,
4769 .{ .reg = reg.dwarfNum() },4740 .{ .reg = reg.dwarfNum() },
4770 ) catch |err| return func.fail("failed to generate debug info: {s}", .{@errorName(err)}),4741 ) catch |err| return func.fail("failed to generate debug info: {s}", .{@errorName(err)}),
...@@ -4777,6 +4748,8 @@ fn genArgDbgInfo(func: *const Func, inst: Air.Inst.Index, mcv: MCValue) InnerErr...@@ -4777,6 +4748,8 @@ fn genArgDbgInfo(func: *const Func, inst: Air.Inst.Index, mcv: MCValue) InnerErr
4777}4748}
47784749
4779fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void {4750fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void {
4751 const zcu = func.pt.zcu;
4752
4780 var arg_index = func.arg_index;4753 var arg_index = func.arg_index;
47814754
4782 // we skip over args that have no bits4755 // we skip over args that have no bits
...@@ -4793,7 +4766,14 @@ fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void {...@@ -4793,7 +4766,14 @@ fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void {
47934766
4794 try func.genCopy(arg_ty, dst_mcv, src_mcv);4767 try func.genCopy(arg_ty, dst_mcv, src_mcv);
47954768
4796 try func.genArgDbgInfo(inst, src_mcv);4769 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
4770 // can delete `func.func_index` if this logic is moved to emit
4771 const func_zir = zcu.funcInfo(func.func_index).zir_body_inst.resolveFull(&zcu.intern_pool).?;
4772 const file = zcu.fileByIndex(func_zir.file);
4773 const zir = &file.zir.?;
4774 const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
4775
4776 try func.genArgDbgInfo(name, arg_ty, src_mcv);
4797 break :result dst_mcv;4777 break :result dst_mcv;
4798 };4778 };
47994779
...@@ -5273,6 +5253,9 @@ fn genVarDbgInfo(...@@ -5273,6 +5253,9 @@ fn genVarDbgInfo(
5273 mcv: MCValue,5253 mcv: MCValue,
5274 name: []const u8,5254 name: []const u8,
5275) !void {5255) !void {
5256 // TODO: Add a pseudo-instruction or something to defer this work until Emit.
5257 // We aren't allowed to interact with linker state here.
5258 if (true) return;
5276 switch (func.debug_output) {5259 switch (func.debug_output) {
5277 .dwarf => |dwarf| {5260 .dwarf => |dwarf| {
5278 const loc: link.File.Dwarf.Loc = switch (mcv) {5261 const loc: link.File.Dwarf.Loc = switch (mcv) {
src/arch/riscv64/Emit.zig+2-2
...@@ -50,8 +50,8 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -50,8 +50,8 @@ pub fn emitMir(emit: *Emit) Error!void {
50 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;50 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
51 const sym = zo.symbol(symbol.sym_index);51 const sym = zo.symbol(symbol.sym_index);
5252
53 if (sym.flags.is_extern_ptr and emit.lower.pic) {53 if (emit.lower.pic) {
54 return emit.fail("emit GOT relocation for symbol '{s}'", .{sym.name(elf_file)});54 return emit.fail("know when to emit GOT relocation for symbol '{s}'", .{sym.name(elf_file)});
55 }55 }
5656
57 const hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);57 const hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
src/arch/riscv64/Mir.zig+48
...@@ -109,6 +109,48 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {...@@ -109,6 +109,48 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
109 mir.* = undefined;109 mir.* = undefined;
110}110}
111111
112pub fn emit(
113 mir: Mir,
114 lf: *link.File,
115 pt: Zcu.PerThread,
116 src_loc: Zcu.LazySrcLoc,
117 func_index: InternPool.Index,
118 code: *std.ArrayListUnmanaged(u8),
119 debug_output: link.File.DebugInfoOutput,
120) codegen.CodeGenError!void {
121 const zcu = pt.zcu;
122 const comp = zcu.comp;
123 const gpa = comp.gpa;
124 const func = zcu.funcInfo(func_index);
125 const fn_info = zcu.typeToFunc(.fromInterned(func.ty)).?;
126 const nav = func.owner_nav;
127 const mod = zcu.navFileScope(nav).mod.?;
128 var e: Emit = .{
129 .lower = .{
130 .pt = pt,
131 .allocator = gpa,
132 .mir = mir,
133 .cc = fn_info.cc,
134 .src_loc = src_loc,
135 .output_mode = comp.config.output_mode,
136 .link_mode = comp.config.link_mode,
137 .pic = mod.pic,
138 },
139 .bin_file = lf,
140 .debug_output = debug_output,
141 .code = code,
142 .prev_di_pc = 0,
143 .prev_di_line = func.lbrace_line,
144 .prev_di_column = func.lbrace_column,
145 };
146 defer e.deinit();
147 e.emitMir() catch |err| switch (err) {
148 error.LowerFail, error.EmitFail => return zcu.codegenFailMsg(nav, e.lower.err_msg.?),
149 error.InvalidInstruction => return zcu.codegenFail(nav, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}),
150 else => |err1| return err1,
151 };
152}
153
112pub const FrameLoc = struct {154pub const FrameLoc = struct {
113 base: Register,155 base: Register,
114 disp: i32,156 disp: i32,
...@@ -202,3 +244,9 @@ const FrameIndex = bits.FrameIndex;...@@ -202,3 +244,9 @@ const FrameIndex = bits.FrameIndex;
202const FrameAddr = @import("CodeGen.zig").FrameAddr;244const FrameAddr = @import("CodeGen.zig").FrameAddr;
203const IntegerBitSet = std.bit_set.IntegerBitSet;245const IntegerBitSet = std.bit_set.IntegerBitSet;
204const Mnemonic = @import("mnem.zig").Mnemonic;246const Mnemonic = @import("mnem.zig").Mnemonic;
247
248const InternPool = @import("../../InternPool.zig");
249const Emit = @import("Emit.zig");
250const codegen = @import("../../codegen.zig");
251const link = @import("../../link.zig");
252const Zcu = @import("../../Zcu.zig");
src/arch/sparc64/CodeGen.zig+29-46
...@@ -57,8 +57,6 @@ liveness: Air.Liveness,...@@ -57,8 +57,6 @@ liveness: Air.Liveness,
57bin_file: *link.File,57bin_file: *link.File,
58target: *const std.Target,58target: *const std.Target,
59func_index: InternPool.Index,59func_index: InternPool.Index,
60code: *std.ArrayListUnmanaged(u8),
61debug_output: link.File.DebugInfoOutput,
62err_msg: ?*ErrorMsg,60err_msg: ?*ErrorMsg,
63args: []MCValue,61args: []MCValue,
64ret_mcv: MCValue,62ret_mcv: MCValue,
...@@ -268,11 +266,9 @@ pub fn generate(...@@ -268,11 +266,9 @@ pub fn generate(
268 pt: Zcu.PerThread,266 pt: Zcu.PerThread,
269 src_loc: Zcu.LazySrcLoc,267 src_loc: Zcu.LazySrcLoc,
270 func_index: InternPool.Index,268 func_index: InternPool.Index,
271 air: Air,269 air: *const Air,
272 liveness: Air.Liveness,270 liveness: *const Air.Liveness,
273 code: *std.ArrayListUnmanaged(u8),271) CodeGenError!Mir {
274 debug_output: link.File.DebugInfoOutput,
275) CodeGenError!void {
276 const zcu = pt.zcu;272 const zcu = pt.zcu;
277 const gpa = zcu.gpa;273 const gpa = zcu.gpa;
278 const func = zcu.funcInfo(func_index);274 const func = zcu.funcInfo(func_index);
...@@ -291,13 +287,11 @@ pub fn generate(...@@ -291,13 +287,11 @@ pub fn generate(
291 var function: Self = .{287 var function: Self = .{
292 .gpa = gpa,288 .gpa = gpa,
293 .pt = pt,289 .pt = pt,
294 .air = air,290 .air = air.*,
295 .liveness = liveness,291 .liveness = liveness.*,
296 .target = target,292 .target = target,
297 .bin_file = lf,293 .bin_file = lf,
298 .func_index = func_index,294 .func_index = func_index,
299 .code = code,
300 .debug_output = debug_output,
301 .err_msg = null,295 .err_msg = null,
302 .args = undefined, // populated after `resolveCallingConventionValues`296 .args = undefined, // populated after `resolveCallingConventionValues`
303 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`297 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
...@@ -330,29 +324,13 @@ pub fn generate(...@@ -330,29 +324,13 @@ pub fn generate(
330 else => |e| return e,324 else => |e| return e,
331 };325 };
332326
333 var mir = Mir{327 var mir: Mir = .{
334 .instructions = function.mir_instructions.toOwnedSlice(),328 .instructions = function.mir_instructions.toOwnedSlice(),
335 .extra = try function.mir_extra.toOwnedSlice(gpa),329 .extra = &.{}, // fallible, so populated after errdefer
336 };
337 defer mir.deinit(gpa);
338
339 var emit: Emit = .{
340 .mir = mir,
341 .bin_file = lf,
342 .debug_output = debug_output,
343 .target = target,
344 .src_loc = src_loc,
345 .code = code,
346 .prev_di_pc = 0,
347 .prev_di_line = func.lbrace_line,
348 .prev_di_column = func.lbrace_column,
349 };
350 defer emit.deinit();
351
352 emit.emitMir() catch |err| switch (err) {
353 error.EmitFail => return function.failMsg(emit.err_msg.?),
354 else => |e| return e,
355 };330 };
331 errdefer mir.deinit(gpa);
332 mir.extra = try function.mir_extra.toOwnedSlice(gpa);
333 return mir;
356}334}
357335
358fn gen(self: *Self) !void {336fn gen(self: *Self) !void {
...@@ -1017,23 +995,29 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {...@@ -1017,23 +995,29 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {
1017 self.arg_index += 1;995 self.arg_index += 1;
1018996
1019 const ty = self.typeOfIndex(inst);997 const ty = self.typeOfIndex(inst);
1020998 const mcv: MCValue = blk: {
1021 const arg = self.args[arg_index];999 switch (self.args[arg_index]) {
1022 const mcv = blk: {
1023 switch (arg) {
1024 .stack_offset => |off| {1000 .stack_offset => |off| {
1025 const abi_size = math.cast(u32, ty.abiSize(zcu)) orelse {1001 const abi_size = math.cast(u32, ty.abiSize(zcu)) orelse {
1026 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(pt)});1002 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(pt)});
1027 };1003 };
1028 const offset = off + abi_size;1004 const offset = off + abi_size;
1029 break :blk MCValue{ .stack_offset = offset };1005 break :blk .{ .stack_offset = offset };
1030 },1006 },
1031 else => break :blk arg,1007 else => |mcv| break :blk mcv,
1032 }1008 }
1033 };1009 };
10341010
1035 self.genArgDbgInfo(inst, mcv) catch |err|1011 const func_zir = zcu.funcInfo(self.func_index).zir_body_inst.resolveFull(&zcu.intern_pool).?;
1036 return self.fail("failed to generate debug info for parameter: {s}", .{@errorName(err)});1012 const file = zcu.fileByIndex(func_zir.file);
1013 if (!file.mod.?.strip) {
1014 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
1015 const zir = &file.zir.?;
1016 const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
1017
1018 self.genArgDbgInfo(name, ty, mcv) catch |err|
1019 return self.fail("failed to generate debug info for parameter: {s}", .{@errorName(err)});
1020 }
10371021
1038 if (self.liveness.isUnused(inst))1022 if (self.liveness.isUnused(inst))
1039 return self.finishAirBookkeeping();1023 return self.finishAirBookkeeping();
...@@ -3561,16 +3545,15 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Air....@@ -3561,16 +3545,15 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Air.
3561 self.finishAirBookkeeping();3545 self.finishAirBookkeeping();
3562}3546}
35633547
3564fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {3548fn genArgDbgInfo(self: Self, name: []const u8, ty: Type, mcv: MCValue) !void {
3565 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;3549 // TODO: Add a pseudo-instruction or something to defer this work until Emit.
3566 const ty = arg.ty.toType();3550 // We aren't allowed to interact with linker state here.
3567 if (arg.name == .none) return;3551 if (true) return;
3568
3569 switch (self.debug_output) {3552 switch (self.debug_output) {
3570 .dwarf => |dw| switch (mcv) {3553 .dwarf => |dw| switch (mcv) {
3571 .register => |reg| try dw.genLocalDebugInfo(3554 .register => |reg| try dw.genLocalDebugInfo(
3572 .local_arg,3555 .local_arg,
3573 arg.name.toSlice(self.air),3556 name,
3574 ty,3557 ty,
3575 .{ .reg = reg.dwarfNum() },3558 .{ .reg = reg.dwarfNum() },
3576 ),3559 ),
src/arch/sparc64/Mir.zig+36-1
...@@ -12,7 +12,11 @@ const assert = std.debug.assert;...@@ -12,7 +12,11 @@ const assert = std.debug.assert;
1212
13const Mir = @This();13const Mir = @This();
14const bits = @import("bits.zig");14const bits = @import("bits.zig");
15const Air = @import("../../Air.zig");15const InternPool = @import("../../InternPool.zig");
16const Emit = @import("Emit.zig");
17const codegen = @import("../../codegen.zig");
18const link = @import("../../link.zig");
19const Zcu = @import("../../Zcu.zig");
1620
17const Instruction = bits.Instruction;21const Instruction = bits.Instruction;
18const ASI = bits.Instruction.ASI;22const ASI = bits.Instruction.ASI;
...@@ -370,6 +374,37 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {...@@ -370,6 +374,37 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
370 mir.* = undefined;374 mir.* = undefined;
371}375}
372376
377pub fn emit(
378 mir: Mir,
379 lf: *link.File,
380 pt: Zcu.PerThread,
381 src_loc: Zcu.LazySrcLoc,
382 func_index: InternPool.Index,
383 code: *std.ArrayListUnmanaged(u8),
384 debug_output: link.File.DebugInfoOutput,
385) codegen.CodeGenError!void {
386 const zcu = pt.zcu;
387 const func = zcu.funcInfo(func_index);
388 const nav = func.owner_nav;
389 const mod = zcu.navFileScope(nav).mod.?;
390 var e: Emit = .{
391 .mir = mir,
392 .bin_file = lf,
393 .debug_output = debug_output,
394 .target = &mod.resolved_target.result,
395 .src_loc = src_loc,
396 .code = code,
397 .prev_di_pc = 0,
398 .prev_di_line = func.lbrace_line,
399 .prev_di_column = func.lbrace_column,
400 };
401 defer e.deinit();
402 e.emitMir() catch |err| switch (err) {
403 error.EmitFail => return zcu.codegenFailMsg(nav, e.err_msg.?),
404 else => |err1| return err1,
405 };
406}
407
373/// Returns the requested data, as well as the new index which is at the start of the408/// Returns the requested data, as well as the new index which is at the start of the
374/// trailers for the object.409/// trailers for the object.
375pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } {410pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } {
src/arch/wasm/CodeGen.zig+105-200
...@@ -3,7 +3,6 @@ const builtin = @import("builtin");...@@ -3,7 +3,6 @@ const builtin = @import("builtin");
3const Allocator = std.mem.Allocator;3const Allocator = std.mem.Allocator;
4const assert = std.debug.assert;4const assert = std.debug.assert;
5const testing = std.testing;5const testing = std.testing;
6const leb = std.leb;
7const mem = std.mem;6const mem = std.mem;
8const log = std.log.scoped(.codegen);7const log = std.log.scoped(.codegen);
98
...@@ -18,12 +17,10 @@ const Compilation = @import("../../Compilation.zig");...@@ -18,12 +17,10 @@ const Compilation = @import("../../Compilation.zig");
18const link = @import("../../link.zig");17const link = @import("../../link.zig");
19const Air = @import("../../Air.zig");18const Air = @import("../../Air.zig");
20const Mir = @import("Mir.zig");19const Mir = @import("Mir.zig");
21const Emit = @import("Emit.zig");
22const abi = @import("abi.zig");20const abi = @import("abi.zig");
23const Alignment = InternPool.Alignment;21const Alignment = InternPool.Alignment;
24const errUnionPayloadOffset = codegen.errUnionPayloadOffset;22const errUnionPayloadOffset = codegen.errUnionPayloadOffset;
25const errUnionErrorOffset = codegen.errUnionErrorOffset;23const errUnionErrorOffset = codegen.errUnionErrorOffset;
26const Wasm = link.File.Wasm;
2724
28const target_util = @import("../../target.zig");25const target_util = @import("../../target.zig");
29const libcFloatPrefix = target_util.libcFloatPrefix;26const libcFloatPrefix = target_util.libcFloatPrefix;
...@@ -78,17 +75,24 @@ simd_immediates: std.ArrayListUnmanaged([16]u8) = .empty,...@@ -78,17 +75,24 @@ simd_immediates: std.ArrayListUnmanaged([16]u8) = .empty,
78/// The Target we're emitting (used to call intInfo)75/// The Target we're emitting (used to call intInfo)
79target: *const std.Target,76target: *const std.Target,
80ptr_size: enum { wasm32, wasm64 },77ptr_size: enum { wasm32, wasm64 },
81wasm: *link.File.Wasm,
82pt: Zcu.PerThread,78pt: Zcu.PerThread,
83/// List of MIR Instructions79/// List of MIR Instructions
84mir_instructions: *std.MultiArrayList(Mir.Inst),80mir_instructions: std.MultiArrayList(Mir.Inst),
85/// Contains extra data for MIR81/// Contains extra data for MIR
86mir_extra: *std.ArrayListUnmanaged(u32),82mir_extra: std.ArrayListUnmanaged(u32),
87start_mir_extra_off: u32,
88start_locals_off: u32,
89/// List of all locals' types generated throughout this declaration83/// List of all locals' types generated throughout this declaration
90/// used to emit locals count at start of 'code' section.84/// used to emit locals count at start of 'code' section.
91locals: *std.ArrayListUnmanaged(std.wasm.Valtype),85mir_locals: std.ArrayListUnmanaged(std.wasm.Valtype),
86/// Set of all UAVs referenced by this function. Key is the UAV value, value is the alignment.
87/// `.none` means naturally aligned. An explicit alignment is never less than the natural alignment.
88mir_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
89/// Set of all functions whose address this function has taken and which therefore might be called
90/// via a `call_indirect` function.
91mir_indirect_function_set: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
92/// Set of all function types used by this function. These must be interned by the linker.
93mir_func_tys: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
94/// The number of `error_name_table_ref` instructions emitted.
95error_name_table_ref_count: u32,
92/// When a function is executing, we store the the current stack pointer's value within this local.96/// When a function is executing, we store the the current stack pointer's value within this local.
93/// This value is then used to restore the stack pointer to the original value at the return of the function.97/// This value is then used to restore the stack pointer to the original value at the return of the function.
94initial_stack_value: WValue = .none,98initial_stack_value: WValue = .none,
...@@ -219,7 +223,7 @@ const WValue = union(enum) {...@@ -219,7 +223,7 @@ const WValue = union(enum) {
219 if (local_value < reserved + 2) return; // reserved locals may never be re-used. Also accounts for 2 stack locals.223 if (local_value < reserved + 2) return; // reserved locals may never be re-used. Also accounts for 2 stack locals.
220224
221 const index = local_value - reserved;225 const index = local_value - reserved;
222 const valtype = gen.locals.items[gen.start_locals_off + index];226 const valtype = gen.mir_locals.items[index];
223 switch (valtype) {227 switch (valtype) {
224 .i32 => gen.free_locals_i32.append(gen.gpa, local_value) catch return, // It's ok to fail any of those, a new local can be allocated instead228 .i32 => gen.free_locals_i32.append(gen.gpa, local_value) catch return, // It's ok to fail any of those, a new local can be allocated instead
225 .i64 => gen.free_locals_i64.append(gen.gpa, local_value) catch return,229 .i64 => gen.free_locals_i64.append(gen.gpa, local_value) catch return,
...@@ -716,6 +720,12 @@ pub fn deinit(cg: *CodeGen) void {...@@ -716,6 +720,12 @@ pub fn deinit(cg: *CodeGen) void {
716 cg.free_locals_f32.deinit(gpa);720 cg.free_locals_f32.deinit(gpa);
717 cg.free_locals_f64.deinit(gpa);721 cg.free_locals_f64.deinit(gpa);
718 cg.free_locals_v128.deinit(gpa);722 cg.free_locals_v128.deinit(gpa);
723 cg.mir_instructions.deinit(gpa);
724 cg.mir_extra.deinit(gpa);
725 cg.mir_locals.deinit(gpa);
726 cg.mir_uavs.deinit(gpa);
727 cg.mir_indirect_function_set.deinit(gpa);
728 cg.mir_func_tys.deinit(gpa);
719 cg.* = undefined;729 cg.* = undefined;
720}730}
721731
...@@ -876,7 +886,7 @@ fn addTag(cg: *CodeGen, tag: Mir.Inst.Tag) error{OutOfMemory}!void {...@@ -876,7 +886,7 @@ fn addTag(cg: *CodeGen, tag: Mir.Inst.Tag) error{OutOfMemory}!void {
876}886}
877887
878fn addExtended(cg: *CodeGen, opcode: std.wasm.MiscOpcode) error{OutOfMemory}!void {888fn addExtended(cg: *CodeGen, opcode: std.wasm.MiscOpcode) error{OutOfMemory}!void {
879 const extra_index = cg.extraLen();889 const extra_index: u32 = @intCast(cg.mir_extra.items.len);
880 try cg.mir_extra.append(cg.gpa, @intFromEnum(opcode));890 try cg.mir_extra.append(cg.gpa, @intFromEnum(opcode));
881 try cg.addInst(.{ .tag = .misc_prefix, .data = .{ .payload = extra_index } });891 try cg.addInst(.{ .tag = .misc_prefix, .data = .{ .payload = extra_index } });
882}892}
...@@ -889,10 +899,6 @@ fn addLocal(cg: *CodeGen, tag: Mir.Inst.Tag, local: u32) error{OutOfMemory}!void...@@ -889,10 +899,6 @@ fn addLocal(cg: *CodeGen, tag: Mir.Inst.Tag, local: u32) error{OutOfMemory}!void
889 try cg.addInst(.{ .tag = tag, .data = .{ .local = local } });899 try cg.addInst(.{ .tag = tag, .data = .{ .local = local } });
890}900}
891901
892fn addFuncTy(cg: *CodeGen, tag: Mir.Inst.Tag, i: Wasm.FunctionType.Index) error{OutOfMemory}!void {
893 try cg.addInst(.{ .tag = tag, .data = .{ .func_ty = i } });
894}
895
896/// Accepts an unsigned 32bit integer rather than a signed integer to902/// Accepts an unsigned 32bit integer rather than a signed integer to
897/// prevent us from having to bitcast multiple times as most values903/// prevent us from having to bitcast multiple times as most values
898/// within codegen are represented as unsigned rather than signed.904/// within codegen are represented as unsigned rather than signed.
...@@ -911,7 +917,7 @@ fn addImm64(cg: *CodeGen, imm: u64) error{OutOfMemory}!void {...@@ -911,7 +917,7 @@ fn addImm64(cg: *CodeGen, imm: u64) error{OutOfMemory}!void {
911/// Accepts the index into the list of 128bit-immediates917/// Accepts the index into the list of 128bit-immediates
912fn addImm128(cg: *CodeGen, index: u32) error{OutOfMemory}!void {918fn addImm128(cg: *CodeGen, index: u32) error{OutOfMemory}!void {
913 const simd_values = cg.simd_immediates.items[index];919 const simd_values = cg.simd_immediates.items[index];
914 const extra_index = cg.extraLen();920 const extra_index: u32 = @intCast(cg.mir_extra.items.len);
915 // tag + 128bit value921 // tag + 128bit value
916 try cg.mir_extra.ensureUnusedCapacity(cg.gpa, 5);922 try cg.mir_extra.ensureUnusedCapacity(cg.gpa, 5);
917 cg.mir_extra.appendAssumeCapacity(@intFromEnum(std.wasm.SimdOpcode.v128_const));923 cg.mir_extra.appendAssumeCapacity(@intFromEnum(std.wasm.SimdOpcode.v128_const));
...@@ -956,15 +962,13 @@ fn addExtra(cg: *CodeGen, extra: anytype) error{OutOfMemory}!u32 {...@@ -956,15 +962,13 @@ fn addExtra(cg: *CodeGen, extra: anytype) error{OutOfMemory}!u32 {
956/// Returns the index into `mir_extra`962/// Returns the index into `mir_extra`
957fn addExtraAssumeCapacity(cg: *CodeGen, extra: anytype) error{OutOfMemory}!u32 {963fn addExtraAssumeCapacity(cg: *CodeGen, extra: anytype) error{OutOfMemory}!u32 {
958 const fields = std.meta.fields(@TypeOf(extra));964 const fields = std.meta.fields(@TypeOf(extra));
959 const result = cg.extraLen();965 const result: u32 = @intCast(cg.mir_extra.items.len);
960 inline for (fields) |field| {966 inline for (fields) |field| {
961 cg.mir_extra.appendAssumeCapacity(switch (field.type) {967 cg.mir_extra.appendAssumeCapacity(switch (field.type) {
962 u32 => @field(extra, field.name),968 u32 => @field(extra, field.name),
963 i32 => @bitCast(@field(extra, field.name)),969 i32 => @bitCast(@field(extra, field.name)),
964 InternPool.Index,970 InternPool.Index,
965 InternPool.Nav.Index,971 InternPool.Nav.Index,
966 Wasm.UavsObjIndex,
967 Wasm.UavsExeIndex,
968 => @intFromEnum(@field(extra, field.name)),972 => @intFromEnum(@field(extra, field.name)),
969 else => |field_type| @compileError("Unsupported field type " ++ @typeName(field_type)),973 else => |field_type| @compileError("Unsupported field type " ++ @typeName(field_type)),
970 });974 });
...@@ -1034,18 +1038,12 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void {...@@ -1034,18 +1038,12 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void {
1034 .float32 => |val| try cg.addInst(.{ .tag = .f32_const, .data = .{ .float32 = val } }),1038 .float32 => |val| try cg.addInst(.{ .tag = .f32_const, .data = .{ .float32 = val } }),
1035 .float64 => |val| try cg.addFloat64(val),1039 .float64 => |val| try cg.addFloat64(val),
1036 .nav_ref => |nav_ref| {1040 .nav_ref => |nav_ref| {
1037 const wasm = cg.wasm;1041 const zcu = cg.pt.zcu;
1038 const comp = wasm.base.comp;
1039 const zcu = comp.zcu.?;
1040 const ip = &zcu.intern_pool;1042 const ip = &zcu.intern_pool;
1041 if (ip.getNav(nav_ref.nav_index).isFn(ip)) {1043 if (ip.getNav(nav_ref.nav_index).isFn(ip)) {
1042 assert(nav_ref.offset == 0);1044 assert(nav_ref.offset == 0);
1043 const gop = try wasm.zcu_indirect_function_set.getOrPut(comp.gpa, nav_ref.nav_index);1045 try cg.mir_indirect_function_set.put(cg.gpa, nav_ref.nav_index, {});
1044 if (!gop.found_existing) gop.value_ptr.* = {};1046 try cg.addInst(.{ .tag = .func_ref, .data = .{ .nav_index = nav_ref.nav_index } });
1045 try cg.addInst(.{
1046 .tag = .func_ref,
1047 .data = .{ .indirect_function_table_index = @enumFromInt(gop.index) },
1048 });
1049 } else if (nav_ref.offset == 0) {1047 } else if (nav_ref.offset == 0) {
1050 try cg.addInst(.{ .tag = .nav_ref, .data = .{ .nav_index = nav_ref.nav_index } });1048 try cg.addInst(.{ .tag = .nav_ref, .data = .{ .nav_index = nav_ref.nav_index } });
1051 } else {1049 } else {
...@@ -1061,41 +1059,37 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void {...@@ -1061,41 +1059,37 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void {
1061 }1059 }
1062 },1060 },
1063 .uav_ref => |uav| {1061 .uav_ref => |uav| {
1064 const wasm = cg.wasm;1062 const zcu = cg.pt.zcu;
1065 const comp = wasm.base.comp;
1066 const is_obj = comp.config.output_mode == .Obj;
1067 const zcu = comp.zcu.?;
1068 const ip = &zcu.intern_pool;1063 const ip = &zcu.intern_pool;
1069 if (ip.isFunctionType(ip.typeOf(uav.ip_index))) {1064 assert(!ip.isFunctionType(ip.typeOf(uav.ip_index)));
1070 assert(uav.offset == 0);1065 const gop = try cg.mir_uavs.getOrPut(cg.gpa, uav.ip_index);
1071 const owner_nav = ip.toFunc(uav.ip_index).owner_nav;1066 const this_align: Alignment = a: {
1072 const gop = try wasm.zcu_indirect_function_set.getOrPut(comp.gpa, owner_nav);1067 if (uav.orig_ptr_ty == .none) break :a .none;
1073 if (!gop.found_existing) gop.value_ptr.* = {};1068 const ptr_type = ip.indexToKey(uav.orig_ptr_ty).ptr_type;
1074 try cg.addInst(.{1069 const this_align = ptr_type.flags.alignment;
1075 .tag = .func_ref,1070 if (this_align == .none) break :a .none;
1076 .data = .{ .indirect_function_table_index = @enumFromInt(gop.index) },1071 const abi_align = Type.fromInterned(ptr_type.child).abiAlignment(zcu);
1077 });1072 if (this_align.compare(.lte, abi_align)) break :a .none;
1078 } else if (uav.offset == 0) {1073 break :a this_align;
1074 };
1075 if (!gop.found_existing or
1076 gop.value_ptr.* == .none or
1077 (this_align != .none and this_align.compare(.gt, gop.value_ptr.*)))
1078 {
1079 gop.value_ptr.* = this_align;
1080 }
1081 if (uav.offset == 0) {
1079 try cg.addInst(.{1082 try cg.addInst(.{
1080 .tag = .uav_ref,1083 .tag = .uav_ref,
1081 .data = if (is_obj) .{1084 .data = .{ .ip_index = uav.ip_index },
1082 .uav_obj = try wasm.refUavObj(uav.ip_index, uav.orig_ptr_ty),
1083 } else .{
1084 .uav_exe = try wasm.refUavExe(uav.ip_index, uav.orig_ptr_ty),
1085 },
1086 });1085 });
1087 } else {1086 } else {
1088 try cg.addInst(.{1087 try cg.addInst(.{
1089 .tag = .uav_ref_off,1088 .tag = .uav_ref_off,
1090 .data = .{1089 .data = .{ .payload = try cg.addExtra(@as(Mir.UavRefOff, .{
1091 .payload = if (is_obj) try cg.addExtra(Mir.UavRefOffObj{1090 .value = uav.ip_index,
1092 .uav_obj = try wasm.refUavObj(uav.ip_index, uav.orig_ptr_ty),1091 .offset = uav.offset,
1093 .offset = uav.offset,1092 })) },
1094 }) else try cg.addExtra(Mir.UavRefOffExe{
1095 .uav_exe = try wasm.refUavExe(uav.ip_index, uav.orig_ptr_ty),
1096 .offset = uav.offset,
1097 }),
1098 },
1099 });1093 });
1100 }1094 }
1101 },1095 },
...@@ -1157,106 +1151,12 @@ fn allocLocal(cg: *CodeGen, ty: Type) InnerError!WValue {...@@ -1157,106 +1151,12 @@ fn allocLocal(cg: *CodeGen, ty: Type) InnerError!WValue {
1157/// to use a zero-initialized local.1151/// to use a zero-initialized local.
1158fn ensureAllocLocal(cg: *CodeGen, ty: Type) InnerError!WValue {1152fn ensureAllocLocal(cg: *CodeGen, ty: Type) InnerError!WValue {
1159 const zcu = cg.pt.zcu;1153 const zcu = cg.pt.zcu;
1160 try cg.locals.append(cg.gpa, typeToValtype(ty, zcu, cg.target));1154 try cg.mir_locals.append(cg.gpa, typeToValtype(ty, zcu, cg.target));
1161 const initial_index = cg.local_index;1155 const initial_index = cg.local_index;
1162 cg.local_index += 1;1156 cg.local_index += 1;
1163 return .{ .local = .{ .value = initial_index, .references = 1 } };1157 return .{ .local = .{ .value = initial_index, .references = 1 } };
1164}1158}
11651159
1166pub const Function = extern struct {
1167 /// Index into `Wasm.mir_instructions`.
1168 mir_off: u32,
1169 /// This is unused except for as a safety slice bound and could be removed.
1170 mir_len: u32,
1171 /// Index into `Wasm.mir_extra`.
1172 mir_extra_off: u32,
1173 /// This is unused except for as a safety slice bound and could be removed.
1174 mir_extra_len: u32,
1175 locals_off: u32,
1176 locals_len: u32,
1177 prologue: Prologue,
1178
1179 pub const Prologue = extern struct {
1180 flags: Flags,
1181 sp_local: u32,
1182 stack_size: u32,
1183 bottom_stack_local: u32,
1184
1185 pub const Flags = packed struct(u32) {
1186 stack_alignment: Alignment,
1187 padding: u26 = 0,
1188 };
1189
1190 pub const none: Prologue = .{
1191 .sp_local = 0,
1192 .flags = .{ .stack_alignment = .none },
1193 .stack_size = 0,
1194 .bottom_stack_local = 0,
1195 };
1196
1197 pub fn isNone(p: *const Prologue) bool {
1198 return p.flags.stack_alignment != .none;
1199 }
1200 };
1201
1202 pub fn lower(f: *Function, wasm: *Wasm, code: *std.ArrayListUnmanaged(u8)) Allocator.Error!void {
1203 const gpa = wasm.base.comp.gpa;
1204
1205 // Write the locals in the prologue of the function body.
1206 const locals = wasm.all_zcu_locals.items[f.locals_off..][0..f.locals_len];
1207 try code.ensureUnusedCapacity(gpa, 5 + locals.len * 6 + 38);
1208
1209 std.leb.writeUleb128(code.fixedWriter(), @as(u32, @intCast(locals.len))) catch unreachable;
1210 for (locals) |local| {
1211 std.leb.writeUleb128(code.fixedWriter(), @as(u32, 1)) catch unreachable;
1212 code.appendAssumeCapacity(@intFromEnum(local));
1213 }
1214
1215 // Stack management section of function prologue.
1216 const stack_alignment = f.prologue.flags.stack_alignment;
1217 if (stack_alignment.toByteUnits()) |align_bytes| {
1218 const sp_global: Wasm.GlobalIndex = .stack_pointer;
1219 // load stack pointer
1220 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.global_get));
1221 std.leb.writeULEB128(code.fixedWriter(), @intFromEnum(sp_global)) catch unreachable;
1222 // store stack pointer so we can restore it when we return from the function
1223 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_tee));
1224 leb.writeUleb128(code.fixedWriter(), f.prologue.sp_local) catch unreachable;
1225 // get the total stack size
1226 const aligned_stack: i32 = @intCast(stack_alignment.forward(f.prologue.stack_size));
1227 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
1228 leb.writeIleb128(code.fixedWriter(), aligned_stack) catch unreachable;
1229 // subtract it from the current stack pointer
1230 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_sub));
1231 // Get negative stack alignment
1232 const neg_stack_align = @as(i32, @intCast(align_bytes)) * -1;
1233 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
1234 leb.writeIleb128(code.fixedWriter(), neg_stack_align) catch unreachable;
1235 // Bitwise-and the value to get the new stack pointer to ensure the
1236 // pointers are aligned with the abi alignment.
1237 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_and));
1238 // The bottom will be used to calculate all stack pointer offsets.
1239 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_tee));
1240 leb.writeUleb128(code.fixedWriter(), f.prologue.bottom_stack_local) catch unreachable;
1241 // Store the current stack pointer value into the global stack pointer so other function calls will
1242 // start from this value instead and not overwrite the current stack.
1243 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.global_set));
1244 std.leb.writeULEB128(code.fixedWriter(), @intFromEnum(sp_global)) catch unreachable;
1245 }
1246
1247 var emit: Emit = .{
1248 .mir = .{
1249 .instruction_tags = wasm.mir_instructions.items(.tag)[f.mir_off..][0..f.mir_len],
1250 .instruction_datas = wasm.mir_instructions.items(.data)[f.mir_off..][0..f.mir_len],
1251 .extra = wasm.mir_extra.items[f.mir_extra_off..][0..f.mir_extra_len],
1252 },
1253 .wasm = wasm,
1254 .code = code,
1255 };
1256 try emit.lowerToCode();
1257 }
1258};
1259
1260pub const Error = error{1160pub const Error = error{
1261 OutOfMemory,1161 OutOfMemory,
1262 /// Compiler was asked to operate on a number larger than supported.1162 /// Compiler was asked to operate on a number larger than supported.
...@@ -1265,13 +1165,16 @@ pub const Error = error{...@@ -1265,13 +1165,16 @@ pub const Error = error{
1265 CodegenFail,1165 CodegenFail,
1266};1166};
12671167
1268pub fn function(1168pub fn generate(
1269 wasm: *Wasm,1169 bin_file: *link.File,
1270 pt: Zcu.PerThread,1170 pt: Zcu.PerThread,
1171 src_loc: Zcu.LazySrcLoc,
1271 func_index: InternPool.Index,1172 func_index: InternPool.Index,
1272 air: Air,1173 air: *const Air,
1273 liveness: Air.Liveness,1174 liveness: *const Air.Liveness,
1274) Error!Function {1175) Error!Mir {
1176 _ = src_loc;
1177 _ = bin_file;
1275 const zcu = pt.zcu;1178 const zcu = pt.zcu;
1276 const gpa = zcu.gpa;1179 const gpa = zcu.gpa;
1277 const cg = zcu.funcInfo(func_index);1180 const cg = zcu.funcInfo(func_index);
...@@ -1279,10 +1182,8 @@ pub fn function(...@@ -1279,10 +1182,8 @@ pub fn function(
1279 const target = &file_scope.mod.?.resolved_target.result;1182 const target = &file_scope.mod.?.resolved_target.result;
1280 const fn_ty = zcu.navValue(cg.owner_nav).typeOf(zcu);1183 const fn_ty = zcu.navValue(cg.owner_nav).typeOf(zcu);
1281 const fn_info = zcu.typeToFunc(fn_ty).?;1184 const fn_info = zcu.typeToFunc(fn_ty).?;
1282 const ip = &zcu.intern_pool;1185 const ret_ty: Type = .fromInterned(fn_info.return_type);
1283 const fn_ty_index = try wasm.internFunctionType(fn_info.cc, fn_info.param_types.get(ip), .fromInterned(fn_info.return_type), target);1186 const any_returns = !firstParamSRet(fn_info.cc, ret_ty, zcu, target) and ret_ty.hasRuntimeBitsIgnoreComptime(zcu);
1284 const returns = fn_ty_index.ptr(wasm).returns.slice(wasm);
1285 const any_returns = returns.len != 0;
12861187
1287 var cc_result = try resolveCallingConventionValues(zcu, fn_ty, target);1188 var cc_result = try resolveCallingConventionValues(zcu, fn_ty, target);
1288 defer cc_result.deinit(gpa);1189 defer cc_result.deinit(gpa);
...@@ -1290,8 +1191,8 @@ pub fn function(...@@ -1290,8 +1191,8 @@ pub fn function(
1290 var code_gen: CodeGen = .{1191 var code_gen: CodeGen = .{
1291 .gpa = gpa,1192 .gpa = gpa,
1292 .pt = pt,1193 .pt = pt,
1293 .air = air,1194 .air = air.*,
1294 .liveness = liveness,1195 .liveness = liveness.*,
1295 .owner_nav = cg.owner_nav,1196 .owner_nav = cg.owner_nav,
1296 .target = target,1197 .target = target,
1297 .ptr_size = switch (target.cpu.arch) {1198 .ptr_size = switch (target.cpu.arch) {
...@@ -1299,31 +1200,33 @@ pub fn function(...@@ -1299,31 +1200,33 @@ pub fn function(
1299 .wasm64 => .wasm64,1200 .wasm64 => .wasm64,
1300 else => unreachable,1201 else => unreachable,
1301 },1202 },
1302 .wasm = wasm,
1303 .func_index = func_index,1203 .func_index = func_index,
1304 .args = cc_result.args,1204 .args = cc_result.args,
1305 .return_value = cc_result.return_value,1205 .return_value = cc_result.return_value,
1306 .local_index = cc_result.local_index,1206 .local_index = cc_result.local_index,
1307 .mir_instructions = &wasm.mir_instructions,1207 .mir_instructions = .empty,
1308 .mir_extra = &wasm.mir_extra,1208 .mir_extra = .empty,
1309 .locals = &wasm.all_zcu_locals,1209 .mir_locals = .empty,
1310 .start_mir_extra_off = @intCast(wasm.mir_extra.items.len),1210 .mir_uavs = .empty,
1311 .start_locals_off = @intCast(wasm.all_zcu_locals.items.len),1211 .mir_indirect_function_set = .empty,
1212 .mir_func_tys = .empty,
1213 .error_name_table_ref_count = 0,
1312 };1214 };
1313 defer code_gen.deinit();1215 defer code_gen.deinit();
13141216
1315 return functionInner(&code_gen, any_returns) catch |err| switch (err) {1217 try code_gen.mir_func_tys.putNoClobber(gpa, fn_ty.toIntern(), {});
1316 error.CodegenFail => return error.CodegenFail,1218
1219 return generateInner(&code_gen, any_returns) catch |err| switch (err) {
1220 error.CodegenFail,
1221 error.OutOfMemory,
1222 error.Overflow,
1223 => |e| return e,
1317 else => |e| return code_gen.fail("failed to generate function: {s}", .{@errorName(e)}),1224 else => |e| return code_gen.fail("failed to generate function: {s}", .{@errorName(e)}),
1318 };1225 };
1319}1226}
13201227
1321fn functionInner(cg: *CodeGen, any_returns: bool) InnerError!Function {1228fn generateInner(cg: *CodeGen, any_returns: bool) InnerError!Mir {
1322 const wasm = cg.wasm;
1323 const zcu = cg.pt.zcu;1229 const zcu = cg.pt.zcu;
1324
1325 const start_mir_off: u32 = @intCast(wasm.mir_instructions.len);
1326
1327 try cg.branches.append(cg.gpa, .{});1230 try cg.branches.append(cg.gpa, .{});
1328 // clean up outer branch1231 // clean up outer branch
1329 defer {1232 defer {
...@@ -1347,20 +1250,25 @@ fn functionInner(cg: *CodeGen, any_returns: bool) InnerError!Function {...@@ -1347,20 +1250,25 @@ fn functionInner(cg: *CodeGen, any_returns: bool) InnerError!Function {
1347 try cg.addTag(.end);1250 try cg.addTag(.end);
1348 try cg.addTag(.dbg_epilogue_begin);1251 try cg.addTag(.dbg_epilogue_begin);
13491252
1350 return .{1253 var mir: Mir = .{
1351 .mir_off = start_mir_off,1254 .instructions = cg.mir_instructions.toOwnedSlice(),
1352 .mir_len = @intCast(wasm.mir_instructions.len - start_mir_off),1255 .extra = &.{}, // fallible so assigned after errdefer
1353 .mir_extra_off = cg.start_mir_extra_off,1256 .locals = &.{}, // fallible so assigned after errdefer
1354 .mir_extra_len = cg.extraLen(),
1355 .locals_off = cg.start_locals_off,
1356 .locals_len = @intCast(wasm.all_zcu_locals.items.len - cg.start_locals_off),
1357 .prologue = if (cg.initial_stack_value == .none) .none else .{1257 .prologue = if (cg.initial_stack_value == .none) .none else .{
1358 .sp_local = cg.initial_stack_value.local.value,1258 .sp_local = cg.initial_stack_value.local.value,
1359 .flags = .{ .stack_alignment = cg.stack_alignment },1259 .flags = .{ .stack_alignment = cg.stack_alignment },
1360 .stack_size = cg.stack_size,1260 .stack_size = cg.stack_size,
1361 .bottom_stack_local = cg.bottom_stack_value.local.value,1261 .bottom_stack_local = cg.bottom_stack_value.local.value,
1362 },1262 },
1263 .uavs = cg.mir_uavs.move(),
1264 .indirect_function_set = cg.mir_indirect_function_set.move(),
1265 .func_tys = cg.mir_func_tys.move(),
1266 .error_name_table_ref_count = cg.error_name_table_ref_count,
1363 };1267 };
1268 errdefer mir.deinit(cg.gpa);
1269 mir.extra = try cg.mir_extra.toOwnedSlice(cg.gpa);
1270 mir.locals = try cg.mir_locals.toOwnedSlice(cg.gpa);
1271 return mir;
1364}1272}
13651273
1366const CallWValues = struct {1274const CallWValues = struct {
...@@ -1969,7 +1877,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1969,7 +1877,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1969 .dbg_inline_block => cg.airDbgInlineBlock(inst),1877 .dbg_inline_block => cg.airDbgInlineBlock(inst),
1970 .dbg_var_ptr => cg.airDbgVar(inst, .local_var, true),1878 .dbg_var_ptr => cg.airDbgVar(inst, .local_var, true),
1971 .dbg_var_val => cg.airDbgVar(inst, .local_var, false),1879 .dbg_var_val => cg.airDbgVar(inst, .local_var, false),
1972 .dbg_arg_inline => cg.airDbgVar(inst, .local_arg, false),1880 .dbg_arg_inline => cg.airDbgVar(inst, .arg, false),
19731881
1974 .call => cg.airCall(inst, .auto),1882 .call => cg.airCall(inst, .auto),
1975 .call_always_tail => cg.airCall(inst, .always_tail),1883 .call_always_tail => cg.airCall(inst, .always_tail),
...@@ -2220,7 +2128,6 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2220,7 +2128,6 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2220}2128}
22212129
2222fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) InnerError!void {2130fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) InnerError!void {
2223 const wasm = cg.wasm;
2224 if (modifier == .always_tail) return cg.fail("TODO implement tail calls for wasm", .{});2131 if (modifier == .always_tail) return cg.fail("TODO implement tail calls for wasm", .{});
2225 const pl_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;2132 const pl_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
2226 const extra = cg.air.extraData(Air.Call, pl_op.payload);2133 const extra = cg.air.extraData(Air.Call, pl_op.payload);
...@@ -2277,8 +2184,11 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie...@@ -2277,8 +2184,11 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
2277 const operand = try cg.resolveInst(pl_op.operand);2184 const operand = try cg.resolveInst(pl_op.operand);
2278 try cg.emitWValue(operand);2185 try cg.emitWValue(operand);
22792186
2280 const fn_type_index = try wasm.internFunctionType(fn_info.cc, fn_info.param_types.get(ip), .fromInterned(fn_info.return_type), cg.target);2187 try cg.mir_func_tys.put(cg.gpa, fn_ty.toIntern(), {});
2281 try cg.addFuncTy(.call_indirect, fn_type_index);2188 try cg.addInst(.{
2189 .tag = .call_indirect,
2190 .data = .{ .ip_index = fn_ty.toIntern() },
2191 });
2282 }2192 }
22832193
2284 const result_value = result_value: {2194 const result_value = result_value: {
...@@ -2449,7 +2359,7 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr...@@ -2449,7 +2359,7 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr
2449 try cg.emitWValue(lhs);2359 try cg.emitWValue(lhs);
2450 try cg.lowerToStack(rhs);2360 try cg.lowerToStack(rhs);
2451 // TODO: Add helper functions for simd opcodes2361 // TODO: Add helper functions for simd opcodes
2452 const extra_index = cg.extraLen();2362 const extra_index: u32 = @intCast(cg.mir_extra.items.len);
2453 // stores as := opcode, offset, alignment (opcode::memarg)2363 // stores as := opcode, offset, alignment (opcode::memarg)
2454 try cg.mir_extra.appendSlice(cg.gpa, &[_]u32{2364 try cg.mir_extra.appendSlice(cg.gpa, &[_]u32{
2455 @intFromEnum(std.wasm.SimdOpcode.v128_store),2365 @intFromEnum(std.wasm.SimdOpcode.v128_store),
...@@ -2574,7 +2484,7 @@ fn load(cg: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValue...@@ -2574,7 +2484,7 @@ fn load(cg: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValue
25742484
2575 if (ty.zigTypeTag(zcu) == .vector) {2485 if (ty.zigTypeTag(zcu) == .vector) {
2576 // TODO: Add helper functions for simd opcodes2486 // TODO: Add helper functions for simd opcodes
2577 const extra_index = cg.extraLen();2487 const extra_index: u32 = @intCast(cg.mir_extra.items.len);
2578 // stores as := opcode, offset, alignment (opcode::memarg)2488 // stores as := opcode, offset, alignment (opcode::memarg)
2579 try cg.mir_extra.appendSlice(cg.gpa, &[_]u32{2489 try cg.mir_extra.appendSlice(cg.gpa, &[_]u32{
2580 @intFromEnum(std.wasm.SimdOpcode.v128_load),2490 @intFromEnum(std.wasm.SimdOpcode.v128_load),
...@@ -4971,7 +4881,7 @@ fn airArrayElemVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4971,7 +4881,7 @@ fn airArrayElemVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
49714881
4972 try cg.emitWValue(array);4882 try cg.emitWValue(array);
49734883
4974 const extra_index = cg.extraLen();4884 const extra_index: u32 = @intCast(cg.mir_extra.items.len);
4975 try cg.mir_extra.appendSlice(cg.gpa, &operands);4885 try cg.mir_extra.appendSlice(cg.gpa, &operands);
4976 try cg.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });4886 try cg.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
49774887
...@@ -5123,7 +5033,7 @@ fn airSplat(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5123,7 +5033,7 @@ fn airSplat(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5123 else => break :blk, // Cannot make use of simd-instructions5033 else => break :blk, // Cannot make use of simd-instructions
5124 };5034 };
5125 try cg.emitWValue(operand);5035 try cg.emitWValue(operand);
5126 const extra_index: u32 = cg.extraLen();5036 const extra_index: u32 = @intCast(cg.mir_extra.items.len);
5127 // stores as := opcode, offset, alignment (opcode::memarg)5037 // stores as := opcode, offset, alignment (opcode::memarg)
5128 try cg.mir_extra.appendSlice(cg.gpa, &[_]u32{5038 try cg.mir_extra.appendSlice(cg.gpa, &[_]u32{
5129 opcode,5039 opcode,
...@@ -5142,7 +5052,7 @@ fn airSplat(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5142,7 +5052,7 @@ fn airSplat(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5142 else => break :blk, // Cannot make use of simd-instructions5052 else => break :blk, // Cannot make use of simd-instructions
5143 };5053 };
5144 try cg.emitWValue(operand);5054 try cg.emitWValue(operand);
5145 const extra_index = cg.extraLen();5055 const extra_index: u32 = @intCast(cg.mir_extra.items.len);
5146 try cg.mir_extra.append(cg.gpa, opcode);5056 try cg.mir_extra.append(cg.gpa, opcode);
5147 try cg.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });5057 try cg.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
5148 return cg.finishAir(inst, .stack, &.{ty_op.operand});5058 return cg.finishAir(inst, .stack, &.{ty_op.operand});
...@@ -5246,7 +5156,7 @@ fn airShuffleTwo(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5246,7 +5156,7 @@ fn airShuffleTwo(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5246 }5156 }
5247 try cg.emitWValue(operand_a);5157 try cg.emitWValue(operand_a);
5248 try cg.emitWValue(operand_b);5158 try cg.emitWValue(operand_b);
5249 const extra_index = cg.extraLen();5159 const extra_index: u32 = @intCast(cg.mir_extra.items.len);
5250 try cg.mir_extra.appendSlice(cg.gpa, &.{5160 try cg.mir_extra.appendSlice(cg.gpa, &.{
5251 @intFromEnum(std.wasm.SimdOpcode.i8x16_shuffle),5161 @intFromEnum(std.wasm.SimdOpcode.i8x16_shuffle),
5252 @bitCast(lane_map[0..4].*),5162 @bitCast(lane_map[0..4].*),
...@@ -6016,9 +5926,8 @@ fn airErrorName(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6016,9 +5926,8 @@ fn airErrorName(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6016 const name_ty = Type.slice_const_u8_sentinel_0;5926 const name_ty = Type.slice_const_u8_sentinel_0;
6017 const abi_size = name_ty.abiSize(pt.zcu);5927 const abi_size = name_ty.abiSize(pt.zcu);
60185928
6019 cg.wasm.error_name_table_ref_count += 1;
6020
6021 // Lowers to a i32.const or i64.const with the error table memory address.5929 // Lowers to a i32.const or i64.const with the error table memory address.
5930 cg.error_name_table_ref_count += 1;
6022 try cg.addTag(.error_name_table_ref);5931 try cg.addTag(.error_name_table_ref);
6023 try cg.emitWValue(operand);5932 try cg.emitWValue(operand);
6024 switch (cg.ptr_size) {5933 switch (cg.ptr_size) {
...@@ -6046,7 +5955,7 @@ fn airPtrSliceFieldPtr(cg: *CodeGen, inst: Air.Inst.Index, offset: u32) InnerErr...@@ -6046,7 +5955,7 @@ fn airPtrSliceFieldPtr(cg: *CodeGen, inst: Air.Inst.Index, offset: u32) InnerErr
60465955
6047/// NOTE: Allocates place for result on virtual stack, when integer size > 64 bits5956/// NOTE: Allocates place for result on virtual stack, when integer size > 64 bits
6048fn intZeroValue(cg: *CodeGen, ty: Type) InnerError!WValue {5957fn intZeroValue(cg: *CodeGen, ty: Type) InnerError!WValue {
6049 const zcu = cg.wasm.base.comp.zcu.?;5958 const zcu = cg.pt.zcu;
6050 const int_info = ty.intInfo(zcu);5959 const int_info = ty.intInfo(zcu);
6051 const wasm_bits = toWasmBits(int_info.bits) orelse {5960 const wasm_bits = toWasmBits(int_info.bits) orelse {
6052 return cg.fail("TODO: Implement intZeroValue for integer bitsize: {d}", .{int_info.bits});5961 return cg.fail("TODO: Implement intZeroValue for integer bitsize: {d}", .{int_info.bits});
...@@ -6518,7 +6427,7 @@ fn airDbgInlineBlock(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6518,7 +6427,7 @@ fn airDbgInlineBlock(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6518fn airDbgVar(6427fn airDbgVar(
6519 cg: *CodeGen,6428 cg: *CodeGen,
6520 inst: Air.Inst.Index,6429 inst: Air.Inst.Index,
6521 local_tag: link.File.Dwarf.WipNav.LocalTag,6430 local_tag: link.File.Dwarf.WipNav.LocalVarTag,
6522 is_ptr: bool,6431 is_ptr: bool,
6523) InnerError!void {6432) InnerError!void {
6524 _ = is_ptr;6433 _ = is_ptr;
...@@ -7673,7 +7582,3 @@ fn floatCmpIntrinsic(op: std.math.CompareOperator, bits: u16) Mir.Intrinsic {...@@ -7673,7 +7582,3 @@ fn floatCmpIntrinsic(op: std.math.CompareOperator, bits: u16) Mir.Intrinsic {
7673 },7582 },
7674 };7583 };
7675}7584}
7676
7677fn extraLen(cg: *const CodeGen) u32 {
7678 return @intCast(cg.mir_extra.items.len - cg.start_mir_extra_off);
7679}
src/arch/wasm/Emit.zig+25-14
...@@ -31,8 +31,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -31,8 +31,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {
31 const target = &comp.root_mod.resolved_target.result;31 const target = &comp.root_mod.resolved_target.result;
32 const is_wasm32 = target.cpu.arch == .wasm32;32 const is_wasm32 = target.cpu.arch == .wasm32;
3333
34 const tags = mir.instruction_tags;34 const tags = mir.instructions.items(.tag);
35 const datas = mir.instruction_datas;35 const datas = mir.instructions.items(.data);
36 var inst: u32 = 0;36 var inst: u32 = 0;
3737
38 loop: switch (tags[inst]) {38 loop: switch (tags[inst]) {
...@@ -50,18 +50,19 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -50,18 +50,19 @@ pub fn lowerToCode(emit: *Emit) Error!void {
50 },50 },
51 .uav_ref => {51 .uav_ref => {
52 if (is_obj) {52 if (is_obj) {
53 try uavRefOffObj(wasm, code, .{ .uav_obj = datas[inst].uav_obj, .offset = 0 }, is_wasm32);53 try uavRefObj(wasm, code, datas[inst].ip_index, 0, is_wasm32);
54 } else {54 } else {
55 try uavRefOffExe(wasm, code, .{ .uav_exe = datas[inst].uav_exe, .offset = 0 }, is_wasm32);55 try uavRefExe(wasm, code, datas[inst].ip_index, 0, is_wasm32);
56 }56 }
57 inst += 1;57 inst += 1;
58 continue :loop tags[inst];58 continue :loop tags[inst];
59 },59 },
60 .uav_ref_off => {60 .uav_ref_off => {
61 const extra = mir.extraData(Mir.UavRefOff, datas[inst].payload).data;
61 if (is_obj) {62 if (is_obj) {
62 try uavRefOffObj(wasm, code, mir.extraData(Mir.UavRefOffObj, datas[inst].payload).data, is_wasm32);63 try uavRefObj(wasm, code, extra.value, extra.offset, is_wasm32);
63 } else {64 } else {
64 try uavRefOffExe(wasm, code, mir.extraData(Mir.UavRefOffExe, datas[inst].payload).data, is_wasm32);65 try uavRefExe(wasm, code, extra.value, extra.offset, is_wasm32);
65 }66 }
66 inst += 1;67 inst += 1;
67 continue :loop tags[inst];68 continue :loop tags[inst];
...@@ -77,11 +78,14 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -77,11 +78,14 @@ pub fn lowerToCode(emit: *Emit) Error!void {
77 continue :loop tags[inst];78 continue :loop tags[inst];
78 },79 },
79 .func_ref => {80 .func_ref => {
81 const indirect_func_idx: Wasm.ZcuIndirectFunctionSetIndex = @enumFromInt(
82 wasm.zcu_indirect_function_set.getIndex(datas[inst].nav_index).?,
83 );
80 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));84 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
81 if (is_obj) {85 if (is_obj) {
82 @panic("TODO");86 @panic("TODO");
83 } else {87 } else {
84 leb.writeUleb128(code.fixedWriter(), 1 + @intFromEnum(datas[inst].indirect_function_table_index)) catch unreachable;88 leb.writeUleb128(code.fixedWriter(), 1 + @intFromEnum(indirect_func_idx)) catch unreachable;
85 }89 }
86 inst += 1;90 inst += 1;
87 continue :loop tags[inst];91 continue :loop tags[inst];
...@@ -101,6 +105,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -101,6 +105,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
101 continue :loop tags[inst];105 continue :loop tags[inst];
102 },106 },
103 .error_name_table_ref => {107 .error_name_table_ref => {
108 wasm.error_name_table_ref_count += 1;
104 try code.ensureUnusedCapacity(gpa, 11);109 try code.ensureUnusedCapacity(gpa, 11);
105 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;110 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
106 code.appendAssumeCapacity(@intFromEnum(opcode));111 code.appendAssumeCapacity(@intFromEnum(opcode));
...@@ -176,7 +181,13 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -176,7 +181,13 @@ pub fn lowerToCode(emit: *Emit) Error!void {
176181
177 .call_indirect => {182 .call_indirect => {
178 try code.ensureUnusedCapacity(gpa, 11);183 try code.ensureUnusedCapacity(gpa, 11);
179 const func_ty_index = datas[inst].func_ty;184 const fn_info = comp.zcu.?.typeToFunc(.fromInterned(datas[inst].ip_index)).?;
185 const func_ty_index = wasm.getExistingFunctionType(
186 fn_info.cc,
187 fn_info.param_types.get(&comp.zcu.?.intern_pool),
188 .fromInterned(fn_info.return_type),
189 target,
190 ).?;
180 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call_indirect));191 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call_indirect));
181 if (is_obj) {192 if (is_obj) {
182 try wasm.out_relocs.append(gpa, .{193 try wasm.out_relocs.append(gpa, .{
...@@ -912,7 +923,7 @@ fn encodeMemArg(code: *std.ArrayListUnmanaged(u8), mem_arg: Mir.MemArg) void {...@@ -912,7 +923,7 @@ fn encodeMemArg(code: *std.ArrayListUnmanaged(u8), mem_arg: Mir.MemArg) void {
912 leb.writeUleb128(code.fixedWriter(), mem_arg.offset) catch unreachable;923 leb.writeUleb128(code.fixedWriter(), mem_arg.offset) catch unreachable;
913}924}
914925
915fn uavRefOffObj(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.UavRefOffObj, is_wasm32: bool) !void {926fn uavRefObj(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
916 const comp = wasm.base.comp;927 const comp = wasm.base.comp;
917 const gpa = comp.gpa;928 const gpa = comp.gpa;
918 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;929 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
...@@ -922,14 +933,14 @@ fn uavRefOffObj(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.UavRef...@@ -922,14 +933,14 @@ fn uavRefOffObj(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.UavRef
922933
923 try wasm.out_relocs.append(gpa, .{934 try wasm.out_relocs.append(gpa, .{
924 .offset = @intCast(code.items.len),935 .offset = @intCast(code.items.len),
925 .pointee = .{ .symbol_index = try wasm.uavSymbolIndex(data.uav_obj.key(wasm).*) },936 .pointee = .{ .symbol_index = try wasm.uavSymbolIndex(value) },
926 .tag = if (is_wasm32) .memory_addr_leb else .memory_addr_leb64,937 .tag = if (is_wasm32) .memory_addr_leb else .memory_addr_leb64,
927 .addend = data.offset,938 .addend = offset,
928 });939 });
929 code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10);940 code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10);
930}941}
931942
932fn uavRefOffExe(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.UavRefOffExe, is_wasm32: bool) !void {943fn uavRefExe(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
933 const comp = wasm.base.comp;944 const comp = wasm.base.comp;
934 const gpa = comp.gpa;945 const gpa = comp.gpa;
935 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;946 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
...@@ -937,8 +948,8 @@ fn uavRefOffExe(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.UavRef...@@ -937,8 +948,8 @@ fn uavRefOffExe(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.UavRef
937 try code.ensureUnusedCapacity(gpa, 11);948 try code.ensureUnusedCapacity(gpa, 11);
938 code.appendAssumeCapacity(@intFromEnum(opcode));949 code.appendAssumeCapacity(@intFromEnum(opcode));
939950
940 const addr = wasm.uavAddr(data.uav_exe);951 const addr = wasm.uavAddr(value);
941 leb.writeUleb128(code.fixedWriter(), @as(u32, @intCast(@as(i64, addr) + data.offset))) catch unreachable;952 leb.writeUleb128(code.fixedWriter(), @as(u32, @intCast(@as(i64, addr) + offset))) catch unreachable;
942}953}
943954
944fn navRefOff(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff, is_wasm32: bool) !void {955fn navRefOff(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff, is_wasm32: bool) !void {
src/arch/wasm/Mir.zig+104-19
...@@ -9,16 +9,53 @@...@@ -9,16 +9,53 @@
9const Mir = @This();9const Mir = @This();
10const InternPool = @import("../../InternPool.zig");10const InternPool = @import("../../InternPool.zig");
11const Wasm = @import("../../link/Wasm.zig");11const Wasm = @import("../../link/Wasm.zig");
12const Emit = @import("Emit.zig");
13const Alignment = InternPool.Alignment;
1214
13const builtin = @import("builtin");15const builtin = @import("builtin");
14const std = @import("std");16const std = @import("std");
15const assert = std.debug.assert;17const assert = std.debug.assert;
18const leb = std.leb;
1619
17instruction_tags: []const Inst.Tag,20instructions: std.MultiArrayList(Inst).Slice,
18instruction_datas: []const Inst.Data,
19/// A slice of indexes where the meaning of the data is determined by the21/// A slice of indexes where the meaning of the data is determined by the
20/// `Inst.Tag` value.22/// `Inst.Tag` value.
21extra: []const u32,23extra: []const u32,
24locals: []const std.wasm.Valtype,
25prologue: Prologue,
26
27/// Not directly used by `Emit`, but the linker needs this to merge it with a global set.
28/// Value is the explicit alignment if greater than natural alignment, `.none` otherwise.
29uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
30/// Not directly used by `Emit`, but the linker needs this to merge it with a global set.
31indirect_function_set: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
32/// Not directly used by `Emit`, but the linker needs this to ensure these types are interned.
33func_tys: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
34/// Not directly used by `Emit`, but the linker needs this to add it to its own refcount.
35error_name_table_ref_count: u32,
36
37pub const Prologue = extern struct {
38 flags: Flags,
39 sp_local: u32,
40 stack_size: u32,
41 bottom_stack_local: u32,
42
43 pub const Flags = packed struct(u32) {
44 stack_alignment: Alignment,
45 padding: u26 = 0,
46 };
47
48 pub const none: Prologue = .{
49 .sp_local = 0,
50 .flags = .{ .stack_alignment = .none },
51 .stack_size = 0,
52 .bottom_stack_local = 0,
53 };
54
55 pub fn isNone(p: *const Prologue) bool {
56 return p.flags.stack_alignment != .none;
57 }
58};
2259
23pub const Inst = struct {60pub const Inst = struct {
24 /// The opcode that represents this instruction61 /// The opcode that represents this instruction
...@@ -80,7 +117,7 @@ pub const Inst = struct {...@@ -80,7 +117,7 @@ pub const Inst = struct {
80 /// Lowers to an i32_const which is the index of the function in the117 /// Lowers to an i32_const which is the index of the function in the
81 /// table section.118 /// table section.
82 ///119 ///
83 /// Uses `indirect_function_table_index`.120 /// Uses `nav_index`.
84 func_ref,121 func_ref,
85 /// Inserts debug information about the current line and column122 /// Inserts debug information about the current line and column
86 /// of the source code123 /// of the source code
...@@ -123,7 +160,7 @@ pub const Inst = struct {...@@ -123,7 +160,7 @@ pub const Inst = struct {
123 /// Calls a function pointer by its function signature160 /// Calls a function pointer by its function signature
124 /// and index into the function table.161 /// and index into the function table.
125 ///162 ///
126 /// Uses `func_ty`163 /// Uses `ip_index`; the `InternPool.Index` is the function type.
127 call_indirect,164 call_indirect,
128 /// Calls a function by its index.165 /// Calls a function by its index.
129 ///166 ///
...@@ -611,11 +648,7 @@ pub const Inst = struct {...@@ -611,11 +648,7 @@ pub const Inst = struct {
611648
612 ip_index: InternPool.Index,649 ip_index: InternPool.Index,
613 nav_index: InternPool.Nav.Index,650 nav_index: InternPool.Nav.Index,
614 func_ty: Wasm.FunctionType.Index,
615 intrinsic: Intrinsic,651 intrinsic: Intrinsic,
616 uav_obj: Wasm.UavsObjIndex,
617 uav_exe: Wasm.UavsExeIndex,
618 indirect_function_table_index: Wasm.ZcuIndirectFunctionSetIndex,
619652
620 comptime {653 comptime {
621 switch (builtin.mode) {654 switch (builtin.mode) {
...@@ -626,10 +659,66 @@ pub const Inst = struct {...@@ -626,10 +659,66 @@ pub const Inst = struct {
626 };659 };
627};660};
628661
629pub fn deinit(self: *Mir, gpa: std.mem.Allocator) void {662pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
630 self.instructions.deinit(gpa);663 mir.instructions.deinit(gpa);
631 gpa.free(self.extra);664 gpa.free(mir.extra);
632 self.* = undefined;665 gpa.free(mir.locals);
666 mir.uavs.deinit(gpa);
667 mir.indirect_function_set.deinit(gpa);
668 mir.func_tys.deinit(gpa);
669 mir.* = undefined;
670}
671
672pub fn lower(mir: *const Mir, wasm: *Wasm, code: *std.ArrayListUnmanaged(u8)) std.mem.Allocator.Error!void {
673 const gpa = wasm.base.comp.gpa;
674
675 // Write the locals in the prologue of the function body.
676 try code.ensureUnusedCapacity(gpa, 5 + mir.locals.len * 6 + 38);
677
678 std.leb.writeUleb128(code.fixedWriter(), @as(u32, @intCast(mir.locals.len))) catch unreachable;
679 for (mir.locals) |local| {
680 std.leb.writeUleb128(code.fixedWriter(), @as(u32, 1)) catch unreachable;
681 code.appendAssumeCapacity(@intFromEnum(local));
682 }
683
684 // Stack management section of function prologue.
685 const stack_alignment = mir.prologue.flags.stack_alignment;
686 if (stack_alignment.toByteUnits()) |align_bytes| {
687 const sp_global: Wasm.GlobalIndex = .stack_pointer;
688 // load stack pointer
689 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.global_get));
690 std.leb.writeULEB128(code.fixedWriter(), @intFromEnum(sp_global)) catch unreachable;
691 // store stack pointer so we can restore it when we return from the function
692 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_tee));
693 leb.writeUleb128(code.fixedWriter(), mir.prologue.sp_local) catch unreachable;
694 // get the total stack size
695 const aligned_stack: i32 = @intCast(stack_alignment.forward(mir.prologue.stack_size));
696 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
697 leb.writeIleb128(code.fixedWriter(), aligned_stack) catch unreachable;
698 // subtract it from the current stack pointer
699 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_sub));
700 // Get negative stack alignment
701 const neg_stack_align = @as(i32, @intCast(align_bytes)) * -1;
702 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
703 leb.writeIleb128(code.fixedWriter(), neg_stack_align) catch unreachable;
704 // Bitwise-and the value to get the new stack pointer to ensure the
705 // pointers are aligned with the abi alignment.
706 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_and));
707 // The bottom will be used to calculate all stack pointer offsets.
708 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_tee));
709 leb.writeUleb128(code.fixedWriter(), mir.prologue.bottom_stack_local) catch unreachable;
710 // Store the current stack pointer value into the global stack pointer so other function calls will
711 // start from this value instead and not overwrite the current stack.
712 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.global_set));
713 std.leb.writeULEB128(code.fixedWriter(), @intFromEnum(sp_global)) catch unreachable;
714 }
715
716 var emit: Emit = .{
717 .mir = mir.*,
718 .wasm = wasm,
719 .code = code,
720 };
721 try emit.lowerToCode();
633}722}
634723
635pub fn extraData(self: *const Mir, comptime T: type, index: usize) struct { data: T, end: usize } {724pub fn extraData(self: *const Mir, comptime T: type, index: usize) struct { data: T, end: usize } {
...@@ -643,6 +732,7 @@ pub fn extraData(self: *const Mir, comptime T: type, index: usize) struct { data...@@ -643,6 +732,7 @@ pub fn extraData(self: *const Mir, comptime T: type, index: usize) struct { data
643 Wasm.UavsObjIndex,732 Wasm.UavsObjIndex,
644 Wasm.UavsExeIndex,733 Wasm.UavsExeIndex,
645 InternPool.Nav.Index,734 InternPool.Nav.Index,
735 InternPool.Index,
646 => @enumFromInt(self.extra[i]),736 => @enumFromInt(self.extra[i]),
647 else => |field_type| @compileError("Unsupported field type " ++ @typeName(field_type)),737 else => |field_type| @compileError("Unsupported field type " ++ @typeName(field_type)),
648 };738 };
...@@ -695,13 +785,8 @@ pub const MemArg = struct {...@@ -695,13 +785,8 @@ pub const MemArg = struct {
695 alignment: u32,785 alignment: u32,
696};786};
697787
698pub const UavRefOffObj = struct {788pub const UavRefOff = struct {
699 uav_obj: Wasm.UavsObjIndex,789 value: InternPool.Index,
700 offset: i32,
701};
702
703pub const UavRefOffExe = struct {
704 uav_exe: Wasm.UavsExeIndex,
705 offset: i32,790 offset: i32,
706};791};
707792
src/arch/x86_64/CodeGen.zig+1964-2233
...@@ -124,13 +124,13 @@ gpa: Allocator,...@@ -124,13 +124,13 @@ gpa: Allocator,
124pt: Zcu.PerThread,124pt: Zcu.PerThread,
125air: Air,125air: Air,
126liveness: Air.Liveness,126liveness: Air.Liveness,
127bin_file: *link.File,
128debug_output: link.File.DebugInfoOutput,
129target: *const std.Target,127target: *const std.Target,
130owner: Owner,128owner: union(enum) {
129 nav_index: InternPool.Nav.Index,
130 lazy_sym: link.File.LazySymbol,
131},
131inline_func: InternPool.Index,132inline_func: InternPool.Index,
132mod: *Module,133mod: *Module,
133arg_index: u32,
134args: []MCValue,134args: []MCValue,
135va_info: union {135va_info: union {
136 sysv: struct {136 sysv: struct {
...@@ -152,6 +152,14 @@ eflags_inst: ?Air.Inst.Index = null,...@@ -152,6 +152,14 @@ eflags_inst: ?Air.Inst.Index = null,
152mir_instructions: std.MultiArrayList(Mir.Inst) = .empty,152mir_instructions: std.MultiArrayList(Mir.Inst) = .empty,
153/// MIR extra data153/// MIR extra data
154mir_extra: std.ArrayListUnmanaged(u32) = .empty,154mir_extra: std.ArrayListUnmanaged(u32) = .empty,
155mir_string_bytes: std.ArrayListUnmanaged(u8) = .empty,
156mir_strings: std.HashMapUnmanaged(
157 u32,
158 void,
159 std.hash_map.StringIndexContext,
160 std.hash_map.default_max_load_percentage,
161) = .empty,
162mir_locals: std.ArrayListUnmanaged(Mir.Local) = .empty,
155mir_table: std.ArrayListUnmanaged(Mir.Inst.Index) = .empty,163mir_table: std.ArrayListUnmanaged(Mir.Inst.Index) = .empty,
156164
157/// The value is an offset into the `Function` `code` from the beginning.165/// The value is an offset into the `Function` `code` from the beginning.
...@@ -194,41 +202,6 @@ loop_switches: std.AutoHashMapUnmanaged(Air.Inst.Index, struct {...@@ -194,41 +202,6 @@ loop_switches: std.AutoHashMapUnmanaged(Air.Inst.Index, struct {
194next_temp_index: Temp.Index = @enumFromInt(0),202next_temp_index: Temp.Index = @enumFromInt(0),
195temp_type: [Temp.Index.max]Type = undefined,203temp_type: [Temp.Index.max]Type = undefined,
196204
197const Owner = union(enum) {
198 nav_index: InternPool.Nav.Index,
199 lazy_sym: link.File.LazySymbol,
200
201 fn getSymbolIndex(owner: Owner, ctx: *CodeGen) !u32 {
202 const pt = ctx.pt;
203 switch (owner) {
204 .nav_index => |nav_index| if (ctx.bin_file.cast(.elf)) |elf_file| {
205 return elf_file.zigObjectPtr().?.getOrCreateMetadataForNav(pt.zcu, nav_index);
206 } else if (ctx.bin_file.cast(.macho)) |macho_file| {
207 return macho_file.getZigObject().?.getOrCreateMetadataForNav(macho_file, nav_index);
208 } else if (ctx.bin_file.cast(.coff)) |coff_file| {
209 const atom = try coff_file.getOrCreateAtomForNav(nav_index);
210 return coff_file.getAtom(atom).getSymbolIndex().?;
211 } else if (ctx.bin_file.cast(.plan9)) |p9_file| {
212 return p9_file.seeNav(pt, nav_index);
213 } else unreachable,
214 .lazy_sym => |lazy_sym| if (ctx.bin_file.cast(.elf)) |elf_file| {
215 return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
216 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
217 } else if (ctx.bin_file.cast(.macho)) |macho_file| {
218 return macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|
219 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
220 } else if (ctx.bin_file.cast(.coff)) |coff_file| {
221 const atom = coff_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
222 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
223 return coff_file.getAtom(atom).getSymbolIndex().?;
224 } else if (ctx.bin_file.cast(.plan9)) |p9_file| {
225 return p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
226 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
227 } else unreachable,
228 }
229 }
230};
231
232const MaskInfo = packed struct {205const MaskInfo = packed struct {
233 kind: enum(u1) { sign, all },206 kind: enum(u1) { sign, all },
234 inverted: bool = false,207 inverted: bool = false,
...@@ -269,37 +242,22 @@ pub const MCValue = union(enum) {...@@ -269,37 +242,22 @@ pub const MCValue = union(enum) {
269 /// The value is in memory at a hard-coded address.242 /// The value is in memory at a hard-coded address.
270 /// If the type is a pointer, it means the pointer address is stored at this memory location.243 /// If the type is a pointer, it means the pointer address is stored at this memory location.
271 memory: u64,244 memory: u64,
272 /// The value is in memory at an address not-yet-allocated by the linker.
273 /// This traditionally corresponds to a relocation emitted in a relocatable object file.
274 load_symbol: bits.SymbolOffset,
275 /// The address of the memory location not-yet-allocated by the linker.
276 lea_symbol: bits.SymbolOffset,
277 /// The value is in memory at an address not-yet-allocated by the linker.
278 /// This must use a non-got pc-relative relocation.
279 load_pcrel: bits.SymbolOffset,
280 /// The address of the memory location not-yet-allocated by the linker.
281 /// This must use a non-got pc-relative relocation.
282 lea_pcrel: bits.SymbolOffset,
283 /// The value is in memory at a constant offset from the address in a register.245 /// The value is in memory at a constant offset from the address in a register.
284 indirect: bits.RegisterOffset,246 indirect: bits.RegisterOffset,
285 /// The value is in memory.
286 /// Payload is a symbol index.
287 load_direct: u32,
288 /// The value is a pointer to a value in memory.
289 /// Payload is a symbol index.
290 lea_direct: u32,
291 /// The value is in memory referenced indirectly via GOT.
292 /// Payload is a symbol index.
293 load_got: u32,
294 /// The value is a pointer to a value referenced indirectly via GOT.
295 /// Payload is a symbol index.
296 lea_got: u32,
297 /// The value stored at an offset from a frame index247 /// The value stored at an offset from a frame index
298 /// Payload is a frame address.248 /// Payload is a frame address.
299 load_frame: bits.FrameAddr,249 load_frame: bits.FrameAddr,
300 /// The address of an offset from a frame index250 /// The address of an offset from a frame index
301 /// Payload is a frame address.251 /// Payload is a frame address.
302 lea_frame: bits.FrameAddr,252 lea_frame: bits.FrameAddr,
253 load_nav: InternPool.Nav.Index,
254 lea_nav: InternPool.Nav.Index,
255 load_uav: InternPool.Key.Ptr.BaseAddr.Uav,
256 lea_uav: InternPool.Key.Ptr.BaseAddr.Uav,
257 load_lazy_sym: link.File.LazySymbol,
258 lea_lazy_sym: link.File.LazySymbol,
259 load_extern_func: Mir.NullTerminatedString,
260 lea_extern_func: Mir.NullTerminatedString,
303 /// Supports integer_per_element abi261 /// Supports integer_per_element abi
304 elementwise_args: packed struct { regs: u3, frame_off: i29, frame_index: FrameIndex },262 elementwise_args: packed struct { regs: u3, frame_off: i29, frame_index: FrameIndex },
305 /// This indicates that we have already allocated a frame index for this instruction,263 /// This indicates that we have already allocated a frame index for this instruction,
...@@ -319,11 +277,14 @@ pub const MCValue = union(enum) {...@@ -319,11 +277,14 @@ pub const MCValue = union(enum) {
319 .register_mask,277 .register_mask,
320 .eflags,278 .eflags,
321 .register_overflow,279 .register_overflow,
322 .lea_symbol,
323 .lea_pcrel,
324 .lea_direct,
325 .lea_got,
326 .lea_frame,280 .lea_frame,
281 .lea_nav,
282 .load_uav,
283 .lea_uav,
284 .load_lazy_sym,
285 .lea_lazy_sym,
286 .lea_extern_func,
287 .load_extern_func,
327 .elementwise_args,288 .elementwise_args,
328 .reserved_frame,289 .reserved_frame,
329 .air_ref,290 .air_ref,
...@@ -333,11 +294,8 @@ pub const MCValue = union(enum) {...@@ -333,11 +294,8 @@ pub const MCValue = union(enum) {
333 .register_triple,294 .register_triple,
334 .register_quadruple,295 .register_quadruple,
335 .memory,296 .memory,
336 .load_symbol,
337 .load_pcrel,
338 .load_got,
339 .load_direct,
340 .indirect,297 .indirect,
298 .load_nav,
341 => true,299 => true,
342 .load_frame => |frame_addr| !frame_addr.index.isNamed(),300 .load_frame => |frame_addr| !frame_addr.index.isNamed(),
343 };301 };
...@@ -353,7 +311,14 @@ pub const MCValue = union(enum) {...@@ -353,7 +311,14 @@ pub const MCValue = union(enum) {
353311
354 fn isMemory(mcv: MCValue) bool {312 fn isMemory(mcv: MCValue) bool {
355 return switch (mcv) {313 return switch (mcv) {
356 .memory, .indirect, .load_frame, .load_symbol => true,314 .memory,
315 .indirect,
316 .load_frame,
317 .load_nav,
318 .load_uav,
319 .load_lazy_sym,
320 .load_extern_func,
321 => true,
357 else => false,322 else => false,
358 };323 };
359 }324 }
...@@ -423,7 +388,7 @@ pub const MCValue = union(enum) {...@@ -423,7 +388,7 @@ pub const MCValue = union(enum) {
423388
424 fn address(mcv: MCValue) MCValue {389 fn address(mcv: MCValue) MCValue {
425 return switch (mcv) {390 return switch (mcv) {
426 .none,391 .none => .none,
427 .unreach,392 .unreach,
428 .dead,393 .dead,
429 .undef,394 .undef,
...@@ -436,11 +401,11 @@ pub const MCValue = union(enum) {...@@ -436,11 +401,11 @@ pub const MCValue = union(enum) {
436 .register_offset,401 .register_offset,
437 .register_overflow,402 .register_overflow,
438 .register_mask,403 .register_mask,
439 .lea_symbol,
440 .lea_pcrel,
441 .lea_direct,
442 .lea_got,
443 .lea_frame,404 .lea_frame,
405 .lea_nav,
406 .lea_uav,
407 .lea_lazy_sym,
408 .lea_extern_func,
444 .elementwise_args,409 .elementwise_args,
445 .reserved_frame,410 .reserved_frame,
446 .air_ref,411 .air_ref,
...@@ -450,17 +415,17 @@ pub const MCValue = union(enum) {...@@ -450,17 +415,17 @@ pub const MCValue = union(enum) {
450 0 => .{ .register = reg_off.reg },415 0 => .{ .register = reg_off.reg },
451 else => .{ .register_offset = reg_off },416 else => .{ .register_offset = reg_off },
452 },417 },
453 .load_direct => |sym_index| .{ .lea_direct = sym_index },
454 .load_got => |sym_index| .{ .lea_got = sym_index },
455 .load_frame => |frame_addr| .{ .lea_frame = frame_addr },418 .load_frame => |frame_addr| .{ .lea_frame = frame_addr },
456 .load_symbol => |sym_off| .{ .lea_symbol = sym_off },419 .load_nav => |nav| .{ .lea_nav = nav },
457 .load_pcrel => |sym_off| .{ .lea_pcrel = sym_off },420 .load_uav => |uav| .{ .lea_uav = uav },
421 .load_lazy_sym => |lazy_sym| .{ .lea_lazy_sym = lazy_sym },
422 .load_extern_func => |extern_func| .{ .lea_extern_func = extern_func },
458 };423 };
459 }424 }
460425
461 fn deref(mcv: MCValue) MCValue {426 fn deref(mcv: MCValue) MCValue {
462 return switch (mcv) {427 return switch (mcv) {
463 .none,428 .none => .none,
464 .unreach,429 .unreach,
465 .dead,430 .dead,
466 .undef,431 .undef,
...@@ -472,11 +437,11 @@ pub const MCValue = union(enum) {...@@ -472,11 +437,11 @@ pub const MCValue = union(enum) {
472 .register_mask,437 .register_mask,
473 .memory,438 .memory,
474 .indirect,439 .indirect,
475 .load_direct,
476 .load_got,
477 .load_frame,440 .load_frame,
478 .load_symbol,441 .load_nav,
479 .load_pcrel,442 .load_uav,
443 .load_lazy_sym,
444 .load_extern_func,
480 .elementwise_args,445 .elementwise_args,
481 .reserved_frame,446 .reserved_frame,
482 .air_ref,447 .air_ref,
...@@ -484,17 +449,17 @@ pub const MCValue = union(enum) {...@@ -484,17 +449,17 @@ pub const MCValue = union(enum) {
484 .immediate => |addr| .{ .memory = addr },449 .immediate => |addr| .{ .memory = addr },
485 .register => |reg| .{ .indirect = .{ .reg = reg } },450 .register => |reg| .{ .indirect = .{ .reg = reg } },
486 .register_offset => |reg_off| .{ .indirect = reg_off },451 .register_offset => |reg_off| .{ .indirect = reg_off },
487 .lea_direct => |sym_index| .{ .load_direct = sym_index },
488 .lea_got => |sym_index| .{ .load_got = sym_index },
489 .lea_frame => |frame_addr| .{ .load_frame = frame_addr },452 .lea_frame => |frame_addr| .{ .load_frame = frame_addr },
490 .lea_symbol => |sym_index| .{ .load_symbol = sym_index },453 .lea_nav => |nav| .{ .load_nav = nav },
491 .lea_pcrel => |sym_index| .{ .load_pcrel = sym_index },454 .lea_uav => |uav| .{ .load_uav = uav },
455 .lea_lazy_sym => |lazy_sym| .{ .load_lazy_sym = lazy_sym },
456 .lea_extern_func => |extern_func| .{ .load_extern_func = extern_func },
492 };457 };
493 }458 }
494459
495 fn offset(mcv: MCValue, off: i32) MCValue {460 fn offset(mcv: MCValue, off: i32) MCValue {
496 return switch (mcv) {461 return switch (mcv) {
497 .none,462 .none => .none,
498 .unreach,463 .unreach,
499 .dead,464 .dead,
500 .undef,465 .undef,
...@@ -510,15 +475,15 @@ pub const MCValue = union(enum) {...@@ -510,15 +475,15 @@ pub const MCValue = union(enum) {
510 .register_mask,475 .register_mask,
511 .memory,476 .memory,
512 .indirect,477 .indirect,
513 .load_direct,
514 .lea_direct,
515 .load_got,
516 .lea_got,
517 .load_frame,478 .load_frame,
518 .load_symbol,479 .load_nav,
519 .lea_symbol,480 .lea_nav,
520 .load_pcrel,481 .load_uav,
521 .lea_pcrel,482 .lea_uav,
483 .load_lazy_sym,
484 .lea_lazy_sym,
485 .load_extern_func,
486 .lea_extern_func,
522 => switch (off) {487 => switch (off) {
523 0 => mcv,488 0 => mcv,
524 else => unreachable, // not offsettable489 else => unreachable, // not offsettable
...@@ -536,7 +501,7 @@ pub const MCValue = union(enum) {...@@ -536,7 +501,7 @@ pub const MCValue = union(enum) {
536501
537 fn mem(mcv: MCValue, function: *CodeGen, mod_rm: Memory.Mod.Rm) !Memory {502 fn mem(mcv: MCValue, function: *CodeGen, mod_rm: Memory.Mod.Rm) !Memory {
538 return switch (mcv) {503 return switch (mcv) {
539 .none,504 .none => .{ .mod = .{ .rm = mod_rm } },
540 .unreach,505 .unreach,
541 .dead,506 .dead,
542 .undef,507 .undef,
...@@ -549,15 +514,13 @@ pub const MCValue = union(enum) {...@@ -549,15 +514,13 @@ pub const MCValue = union(enum) {
549 .register_offset,514 .register_offset,
550 .register_overflow,515 .register_overflow,
551 .register_mask,516 .register_mask,
552 .load_direct,
553 .lea_direct,
554 .load_got,
555 .lea_got,
556 .lea_frame,517 .lea_frame,
557 .elementwise_args,518 .elementwise_args,
558 .reserved_frame,519 .reserved_frame,
559 .lea_symbol,520 .lea_nav,
560 .lea_pcrel,521 .lea_uav,
522 .lea_lazy_sym,
523 .lea_extern_func,
561 => unreachable,524 => unreachable,
562 .memory => |addr| if (std.math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| .{525 .memory => |addr| if (std.math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| .{
563 .base = .{ .reg = .ds },526 .base = .{ .reg = .ds },
...@@ -586,30 +549,10 @@ pub const MCValue = union(enum) {...@@ -586,30 +549,10 @@ pub const MCValue = union(enum) {
586 .disp = frame_addr.off + mod_rm.disp,549 .disp = frame_addr.off + mod_rm.disp,
587 } },550 } },
588 },551 },
589 .load_symbol => |sym_off| {552 .load_nav => |nav| .{ .base = .{ .nav = nav }, .mod = .{ .rm = mod_rm } },
590 assert(sym_off.off == 0);553 .load_uav => |uav| .{ .base = .{ .uav = uav }, .mod = .{ .rm = mod_rm } },
591 return .{554 .load_lazy_sym => |lazy_sym| .{ .base = .{ .lazy_sym = lazy_sym }, .mod = .{ .rm = mod_rm } },
592 .base = .{ .reloc = sym_off.sym_index },555 .load_extern_func => |extern_func| .{ .base = .{ .extern_func = extern_func }, .mod = .{ .rm = mod_rm } },
593 .mod = .{ .rm = .{
594 .size = mod_rm.size,
595 .index = mod_rm.index,
596 .scale = mod_rm.scale,
597 .disp = sym_off.off + mod_rm.disp,
598 } },
599 };
600 },
601 .load_pcrel => |sym_off| {
602 assert(sym_off.off == 0);
603 return .{
604 .base = .{ .pcrel = sym_off.sym_index },
605 .mod = .{ .rm = .{
606 .size = mod_rm.size,
607 .index = mod_rm.index,
608 .scale = mod_rm.scale,
609 .disp = sym_off.off + mod_rm.disp,
610 } },
611 };
612 },
613 .air_ref => |ref| (try function.resolveInst(ref)).mem(function, mod_rm),556 .air_ref => |ref| (try function.resolveInst(ref)).mem(function, mod_rm),
614 };557 };
615 }558 }
...@@ -643,20 +586,20 @@ pub const MCValue = union(enum) {...@@ -643,20 +586,20 @@ pub const MCValue = union(enum) {
643 @as(u8, if (pl.info.inverted) '!' else ' '),586 @as(u8, if (pl.info.inverted) '!' else ' '),
644 @tagName(pl.reg),587 @tagName(pl.reg),
645 }),588 }),
646 .load_symbol => |pl| try writer.print("[sym:{} + 0x{x}]", .{ pl.sym_index, pl.off }),
647 .lea_symbol => |pl| try writer.print("sym:{} + 0x{x}", .{ pl.sym_index, pl.off }),
648 .load_pcrel => |pl| try writer.print("[sym@pcrel:{} + 0x{x}]", .{ pl.sym_index, pl.off }),
649 .lea_pcrel => |pl| try writer.print("sym@pcrel:{} + 0x{x}", .{ pl.sym_index, pl.off }),
650 .indirect => |pl| try writer.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }),589 .indirect => |pl| try writer.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }),
651 .load_direct => |pl| try writer.print("[direct:{d}]", .{pl}),
652 .lea_direct => |pl| try writer.print("direct:{d}", .{pl}),
653 .load_got => |pl| try writer.print("[got:{d}]", .{pl}),
654 .lea_got => |pl| try writer.print("got:{d}", .{pl}),
655 .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }),590 .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }),
591 .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }),
592 .load_nav => |pl| try writer.print("[nav:{d}]", .{@intFromEnum(pl)}),
593 .lea_nav => |pl| try writer.print("nav:{d}", .{@intFromEnum(pl)}),
594 .load_uav => |pl| try writer.print("[uav:{d}]", .{@intFromEnum(pl.val)}),
595 .lea_uav => |pl| try writer.print("uav:{d}", .{@intFromEnum(pl.val)}),
596 .load_lazy_sym => |pl| try writer.print("[lazy:{s}:{d}]", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
597 .lea_lazy_sym => |pl| try writer.print("lazy:{s}:{d}", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
598 .load_extern_func => |pl| try writer.print("[extern:{d}]", .{@intFromEnum(pl)}),
599 .lea_extern_func => |pl| try writer.print("extern:{d}", .{@intFromEnum(pl)}),
656 .elementwise_args => |pl| try writer.print("elementwise:{d}:[{} + 0x{x}]", .{600 .elementwise_args => |pl| try writer.print("elementwise:{d}:[{} + 0x{x}]", .{
657 pl.regs, pl.frame_index, pl.frame_off,601 pl.regs, pl.frame_index, pl.frame_off,
658 }),602 }),
659 .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }),
660 .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}),603 .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}),
661 .air_ref => |pl| try writer.print("(air:0x{x})", .{@intFromEnum(pl)}),604 .air_ref => |pl| try writer.print("(air:0x{x})", .{@intFromEnum(pl)}),
662 }605 }
...@@ -676,16 +619,16 @@ const InstTracking = struct {...@@ -676,16 +619,16 @@ const InstTracking = struct {
676 .undef,619 .undef,
677 .immediate,620 .immediate,
678 .memory,621 .memory,
679 .load_direct,
680 .lea_direct,
681 .load_got,
682 .lea_got,
683 .load_frame,622 .load_frame,
684 .lea_frame,623 .lea_frame,
685 .load_symbol,624 .load_nav,
686 .lea_symbol,625 .lea_nav,
687 .load_pcrel,626 .load_uav,
688 .lea_pcrel,627 .lea_uav,
628 .load_lazy_sym,
629 .lea_lazy_sym,
630 .load_extern_func,
631 .lea_extern_func,
689 => result,632 => result,
690 .dead,633 .dead,
691 .elementwise_args,634 .elementwise_args,
...@@ -779,15 +722,15 @@ const InstTracking = struct {...@@ -779,15 +722,15 @@ const InstTracking = struct {
779 .undef,722 .undef,
780 .immediate,723 .immediate,
781 .memory,724 .memory,
782 .load_direct,
783 .lea_direct,
784 .load_got,
785 .lea_got,
786 .lea_frame,725 .lea_frame,
787 .load_symbol,726 .load_nav,
788 .lea_symbol,727 .lea_nav,
789 .load_pcrel,728 .load_uav,
790 .lea_pcrel,729 .lea_uav,
730 .load_lazy_sym,
731 .lea_lazy_sym,
732 .load_extern_func,
733 .lea_extern_func,
791 => assert(std.meta.eql(self.long, target.long)),734 => assert(std.meta.eql(self.long, target.long)),
792 .dead,735 .dead,
793 .eflags,736 .eflags,
...@@ -972,31 +915,28 @@ pub fn generate(...@@ -972,31 +915,28 @@ pub fn generate(
972 pt: Zcu.PerThread,915 pt: Zcu.PerThread,
973 src_loc: Zcu.LazySrcLoc,916 src_loc: Zcu.LazySrcLoc,
974 func_index: InternPool.Index,917 func_index: InternPool.Index,
975 air: Air,918 air: *const Air,
976 liveness: Air.Liveness,919 liveness: *const Air.Liveness,
977 code: *std.ArrayListUnmanaged(u8),920) codegen.CodeGenError!Mir {
978 debug_output: link.File.DebugInfoOutput,921 _ = bin_file;
979) codegen.CodeGenError!void {
980 const zcu = pt.zcu;922 const zcu = pt.zcu;
981 const comp = zcu.comp;
982 const gpa = zcu.gpa;923 const gpa = zcu.gpa;
983 const ip = &zcu.intern_pool;924 const ip = &zcu.intern_pool;
984 const func = zcu.funcInfo(func_index);925 const func = zcu.funcInfo(func_index);
926 const func_zir = func.zir_body_inst.resolveFull(ip).?;
927 const file = zcu.fileByIndex(func_zir.file);
985 const fn_type: Type = .fromInterned(func.ty);928 const fn_type: Type = .fromInterned(func.ty);
986 const mod = zcu.navFileScope(func.owner_nav).mod.?;929 const mod = file.mod.?;
987930
988 var function: CodeGen = .{931 var function: CodeGen = .{
989 .gpa = gpa,932 .gpa = gpa,
990 .pt = pt,933 .pt = pt,
991 .air = air,934 .air = air.*,
992 .liveness = liveness,935 .liveness = liveness.*,
993 .target = &mod.resolved_target.result,936 .target = &mod.resolved_target.result,
994 .mod = mod,937 .mod = mod,
995 .bin_file = bin_file,
996 .debug_output = debug_output,
997 .owner = .{ .nav_index = func.owner_nav },938 .owner = .{ .nav_index = func.owner_nav },
998 .inline_func = func_index,939 .inline_func = func_index,
999 .arg_index = undefined,
1000 .args = undefined, // populated after `resolveCallingConventionValues`940 .args = undefined, // populated after `resolveCallingConventionValues`
1001 .va_info = undefined, // populated after `resolveCallingConventionValues`941 .va_info = undefined, // populated after `resolveCallingConventionValues`
1002 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`942 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
...@@ -1016,6 +956,9 @@ pub fn generate(...@@ -1016,6 +956,9 @@ pub fn generate(
1016 function.inst_tracking.deinit(gpa);956 function.inst_tracking.deinit(gpa);
1017 function.epilogue_relocs.deinit(gpa);957 function.epilogue_relocs.deinit(gpa);
1018 function.mir_instructions.deinit(gpa);958 function.mir_instructions.deinit(gpa);
959 function.mir_string_bytes.deinit(gpa);
960 function.mir_strings.deinit(gpa);
961 function.mir_locals.deinit(gpa);
1019 function.mir_extra.deinit(gpa);962 function.mir_extra.deinit(gpa);
1020 function.mir_table.deinit(gpa);963 function.mir_table.deinit(gpa);
1021 }964 }
...@@ -1083,14 +1026,14 @@ pub fn generate(...@@ -1083,14 +1026,14 @@ pub fn generate(
1083 );1026 );
1084 }1027 }
10851028
1086 function.gen() catch |err| switch (err) {1029 function.gen(&file.zir.?, func_zir.inst, func.comptime_args, call_info.air_arg_count) catch |err| switch (err) {
1087 error.CodegenFail => return error.CodegenFail,1030 error.CodegenFail => return error.CodegenFail,
1088 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),1031 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
1089 else => |e| return e,1032 else => |e| return e,
1090 };1033 };
10911034
1092 // Drop them off at the rbrace.1035 // Drop them off at the rbrace.
1093 if (debug_output != .none) _ = try function.addInst(.{1036 if (!mod.strip) _ = try function.addInst(.{
1094 .tag = .pseudo,1037 .tag = .pseudo,
1095 .ops = .pseudo_dbg_line_line_column,1038 .ops = .pseudo_dbg_line_line_column,
1096 .data = .{ .line_column = .{1039 .data = .{ .line_column = .{
...@@ -1100,48 +1043,31 @@ pub fn generate(...@@ -1100,48 +1043,31 @@ pub fn generate(
1100 });1043 });
11011044
1102 var mir: Mir = .{1045 var mir: Mir = .{
1103 .instructions = function.mir_instructions.toOwnedSlice(),1046 .instructions = .empty,
1104 .extra = try function.mir_extra.toOwnedSlice(gpa),1047 .extra = &.{},
1105 .table = try function.mir_table.toOwnedSlice(gpa),1048 .string_bytes = &.{},
1106 .frame_locs = function.frame_locs.toOwnedSlice(),1049 .locals = &.{},
1050 .table = &.{},
1051 .frame_locs = .empty,
1107 };1052 };
1108 defer mir.deinit(gpa);1053 errdefer mir.deinit(gpa);
11091054 mir.instructions = function.mir_instructions.toOwnedSlice();
1110 var emit: Emit = .{1055 mir.extra = try function.mir_extra.toOwnedSlice(gpa);
1111 .air = function.air,1056 mir.string_bytes = try function.mir_string_bytes.toOwnedSlice(gpa);
1112 .lower = .{1057 mir.locals = try function.mir_locals.toOwnedSlice(gpa);
1113 .bin_file = bin_file,1058 mir.table = try function.mir_table.toOwnedSlice(gpa);
1114 .target = function.target,1059 mir.frame_locs = function.frame_locs.toOwnedSlice();
1115 .allocator = gpa,1060 return mir;
1116 .mir = mir,1061}
1117 .cc = fn_info.cc,
1118 .src_loc = src_loc,
1119 .output_mode = comp.config.output_mode,
1120 .link_mode = comp.config.link_mode,
1121 .pic = mod.pic,
1122 },
1123 .atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) {
1124 error.CodegenFail => return error.CodegenFail,
1125 else => |e| return e,
1126 },
1127 .debug_output = debug_output,
1128 .code = code,
1129 .prev_di_loc = .{
1130 .line = func.lbrace_line,
1131 .column = func.lbrace_column,
1132 .is_stmt = switch (debug_output) {
1133 .dwarf => |dwarf| dwarf.dwarf.debug_line.header.default_is_stmt,
1134 .plan9 => undefined,
1135 .none => undefined,
1136 },
1137 },
1138 .prev_di_pc = 0,
1139 };
1140 emit.emitMir() catch |err| switch (err) {
1141 error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
11421062
1143 error.InvalidInstruction, error.CannotEncode => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}),1063pub fn getTmpMir(cg: *CodeGen) Mir {
1144 else => |e| return function.fail("emit MIR failed: {s}", .{@errorName(e)}),1064 return .{
1065 .instructions = cg.mir_instructions.slice(),
1066 .extra = cg.mir_extra.items,
1067 .string_bytes = cg.mir_string_bytes.items,
1068 .locals = cg.mir_locals.items,
1069 .table = cg.mir_table.items,
1070 .frame_locs = cg.frame_locs.slice(),
1145 };1071 };
1146}1072}
11471073
...@@ -1153,10 +1079,9 @@ pub fn generateLazy(...@@ -1153,10 +1079,9 @@ pub fn generateLazy(
1153 code: *std.ArrayListUnmanaged(u8),1079 code: *std.ArrayListUnmanaged(u8),
1154 debug_output: link.File.DebugInfoOutput,1080 debug_output: link.File.DebugInfoOutput,
1155) codegen.CodeGenError!void {1081) codegen.CodeGenError!void {
1156 const comp = bin_file.comp;1082 const gpa = pt.zcu.gpa;
1157 const gpa = comp.gpa;
1158 // This function is for generating global code, so we use the root module.1083 // This function is for generating global code, so we use the root module.
1159 const mod = comp.root_mod;1084 const mod = pt.zcu.comp.root_mod;
1160 var function: CodeGen = .{1085 var function: CodeGen = .{
1161 .gpa = gpa,1086 .gpa = gpa,
1162 .pt = pt,1087 .pt = pt,
...@@ -1164,11 +1089,8 @@ pub fn generateLazy(...@@ -1164,11 +1089,8 @@ pub fn generateLazy(
1164 .liveness = undefined,1089 .liveness = undefined,
1165 .target = &mod.resolved_target.result,1090 .target = &mod.resolved_target.result,
1166 .mod = mod,1091 .mod = mod,
1167 .bin_file = bin_file,
1168 .debug_output = debug_output,
1169 .owner = .{ .lazy_sym = lazy_sym },1092 .owner = .{ .lazy_sym = lazy_sym },
1170 .inline_func = undefined,1093 .inline_func = undefined,
1171 .arg_index = undefined,
1172 .args = undefined,1094 .args = undefined,
1173 .va_info = undefined,1095 .va_info = undefined,
1174 .ret_mcv = undefined,1096 .ret_mcv = undefined,
...@@ -1179,6 +1101,9 @@ pub fn generateLazy(...@@ -1179,6 +1101,9 @@ pub fn generateLazy(
1179 defer {1101 defer {
1180 function.inst_tracking.deinit(gpa);1102 function.inst_tracking.deinit(gpa);
1181 function.mir_instructions.deinit(gpa);1103 function.mir_instructions.deinit(gpa);
1104 function.mir_string_bytes.deinit(gpa);
1105 function.mir_strings.deinit(gpa);
1106 function.mir_locals.deinit(gpa);
1182 function.mir_extra.deinit(gpa);1107 function.mir_extra.deinit(gpa);
1183 function.mir_table.deinit(gpa);1108 function.mir_table.deinit(gpa);
1184 }1109 }
...@@ -1194,42 +1119,7 @@ pub fn generateLazy(...@@ -1194,42 +1119,7 @@ pub fn generateLazy(
1194 else => |e| return e,1119 else => |e| return e,
1195 };1120 };
11961121
1197 var mir: Mir = .{1122 try function.getTmpMir().emitLazy(bin_file, pt, src_loc, lazy_sym, code, debug_output);
1198 .instructions = function.mir_instructions.toOwnedSlice(),
1199 .extra = try function.mir_extra.toOwnedSlice(gpa),
1200 .table = try function.mir_table.toOwnedSlice(gpa),
1201 .frame_locs = function.frame_locs.toOwnedSlice(),
1202 };
1203 defer mir.deinit(gpa);
1204
1205 var emit: Emit = .{
1206 .air = function.air,
1207 .lower = .{
1208 .bin_file = bin_file,
1209 .target = function.target,
1210 .allocator = gpa,
1211 .mir = mir,
1212 .cc = .auto,
1213 .src_loc = src_loc,
1214 .output_mode = comp.config.output_mode,
1215 .link_mode = comp.config.link_mode,
1216 .pic = mod.pic,
1217 },
1218 .atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) {
1219 error.CodegenFail => return error.CodegenFail,
1220 else => |e| return e,
1221 },
1222 .debug_output = debug_output,
1223 .code = code,
1224 .prev_di_loc = undefined, // no debug info yet
1225 .prev_di_pc = undefined, // no debug info yet
1226 };
1227 emit.emitMir() catch |err| switch (err) {
1228 error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
1229 error.InvalidInstruction => return function.fail("failed to find a viable x86 instruction (Zig compiler bug)", .{}),
1230 error.CannotEncode => return function.fail("failed to encode x86 instruction (Zig compiler bug)", .{}),
1231 else => |e| return function.fail("failed to emit MIR: {s}", .{@errorName(e)}),
1232 };
1233}1123}
12341124
1235const FormatNavData = struct {1125const FormatNavData = struct {
...@@ -1277,23 +1167,12 @@ fn formatWipMir(...@@ -1277,23 +1167,12 @@ fn formatWipMir(
1277 _: std.fmt.FormatOptions,1167 _: std.fmt.FormatOptions,
1278 writer: anytype,1168 writer: anytype,
1279) @TypeOf(writer).Error!void {1169) @TypeOf(writer).Error!void {
1280 const comp = data.self.bin_file.comp;
1281 const mod = comp.root_mod;
1282 var lower: Lower = .{1170 var lower: Lower = .{
1283 .bin_file = data.self.bin_file,
1284 .target = data.self.target,1171 .target = data.self.target,
1285 .allocator = data.self.gpa,1172 .allocator = data.self.gpa,
1286 .mir = .{1173 .mir = data.self.getTmpMir(),
1287 .instructions = data.self.mir_instructions.slice(),
1288 .extra = data.self.mir_extra.items,
1289 .table = data.self.mir_table.items,
1290 .frame_locs = (std.MultiArrayList(Mir.FrameLoc){}).slice(),
1291 },
1292 .cc = .auto,1174 .cc = .auto,
1293 .src_loc = data.self.src_loc,1175 .src_loc = data.self.src_loc,
1294 .output_mode = comp.config.output_mode,
1295 .link_mode = comp.config.link_mode,
1296 .pic = mod.pic,
1297 };1176 };
1298 var first = true;1177 var first = true;
1299 for ((lower.lowerMir(data.inst) catch |err| switch (err) {1178 for ((lower.lowerMir(data.inst) catch |err| switch (err) {
...@@ -1329,7 +1208,9 @@ fn formatWipMir(...@@ -1329,7 +1208,9 @@ fn formatWipMir(
1329 .pseudo_dbg_epilogue_begin_none,1208 .pseudo_dbg_epilogue_begin_none,
1330 .pseudo_dbg_enter_block_none,1209 .pseudo_dbg_enter_block_none,
1331 .pseudo_dbg_leave_block_none,1210 .pseudo_dbg_leave_block_none,
1211 .pseudo_dbg_arg_none,
1332 .pseudo_dbg_var_args_none,1212 .pseudo_dbg_var_args_none,
1213 .pseudo_dbg_var_none,
1333 .pseudo_dead_none,1214 .pseudo_dead_none,
1334 => {},1215 => {},
1335 .pseudo_dbg_line_stmt_line_column, .pseudo_dbg_line_line_column => try writer.print(1216 .pseudo_dbg_line_stmt_line_column, .pseudo_dbg_line_line_column => try writer.print(
...@@ -1337,57 +1218,40 @@ fn formatWipMir(...@@ -1337,57 +1218,40 @@ fn formatWipMir(
1337 mir_inst.data.line_column,1218 mir_inst.data.line_column,
1338 ),1219 ),
1339 .pseudo_dbg_enter_inline_func, .pseudo_dbg_leave_inline_func => try writer.print(" {}", .{1220 .pseudo_dbg_enter_inline_func, .pseudo_dbg_leave_inline_func => try writer.print(" {}", .{
1340 ip.getNav(ip.indexToKey(mir_inst.data.func).func.owner_nav).name.fmt(ip),1221 ip.getNav(ip.indexToKey(mir_inst.data.ip_index).func.owner_nav).name.fmt(ip),
1341 }),1222 }),
1342 .pseudo_dbg_local_a => try writer.print(" {}", .{mir_inst.data.a.air_inst}),1223 .pseudo_dbg_arg_i_s, .pseudo_dbg_var_i_s => try writer.print(" {d}", .{
1343 .pseudo_dbg_local_ai_s => try writer.print(" {}, {d}", .{1224 @as(i32, @bitCast(mir_inst.data.i.i)),
1344 mir_inst.data.ai.air_inst,
1345 @as(i32, @bitCast(mir_inst.data.ai.i)),
1346 }),1225 }),
1347 .pseudo_dbg_local_ai_u => try writer.print(" {}, {d}", .{1226 .pseudo_dbg_arg_i_u, .pseudo_dbg_var_i_u => try writer.print(" {d}", .{
1348 mir_inst.data.ai.air_inst,1227 mir_inst.data.i.i,
1349 mir_inst.data.ai.i,
1350 }),1228 }),
1351 .pseudo_dbg_local_ai_64 => try writer.print(" {}, {d}", .{1229 .pseudo_dbg_arg_i_64, .pseudo_dbg_var_i_64 => try writer.print(" {d}", .{
1352 mir_inst.data.ai.air_inst,1230 mir_inst.data.i64,
1353 lower.mir.extraData(Mir.Imm64, mir_inst.data.ai.i).data.decode(),
1354 }),1231 }),
1355 .pseudo_dbg_local_as => {1232 .pseudo_dbg_arg_ro, .pseudo_dbg_var_ro => {
1356 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{
1357 .base = .{ .reloc = mir_inst.data.as.sym_index },
1358 }) };
1359 try writer.print(" {}, {}", .{ mir_inst.data.as.air_inst, mem_op.fmt(.m) });
1360 },
1361 .pseudo_dbg_local_aso => {
1362 const sym_off = lower.mir.extraData(bits.SymbolOffset, mir_inst.data.ax.payload).data;
1363 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{1233 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{
1364 .base = .{ .reloc = sym_off.sym_index },1234 .base = .{ .reg = mir_inst.data.ro.reg },
1365 .disp = sym_off.off,1235 .disp = mir_inst.data.ro.off,
1366 }) };1236 }) };
1367 try writer.print(" {}, {}", .{ mir_inst.data.ax.air_inst, mem_op.fmt(.m) });1237 try writer.print(" {}", .{mem_op.fmt(.m)});
1368 },1238 },
1369 .pseudo_dbg_local_aro => {1239 .pseudo_dbg_arg_fa, .pseudo_dbg_var_fa => {
1370 const air_off = lower.mir.extraData(Mir.AirOffset, mir_inst.data.rx.payload).data;
1371 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{1240 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{
1372 .base = .{ .reg = mir_inst.data.rx.r1 },1241 .base = .{ .frame = mir_inst.data.fa.index },
1373 .disp = air_off.off,1242 .disp = mir_inst.data.fa.off,
1374 }) };1243 }) };
1375 try writer.print(" {}, {}", .{ air_off.air_inst, mem_op.fmt(.m) });1244 try writer.print(" {}", .{mem_op.fmt(.m)});
1376 },1245 },
1377 .pseudo_dbg_local_af => {1246 .pseudo_dbg_arg_m, .pseudo_dbg_var_m => {
1378 const frame_addr = lower.mir.extraData(bits.FrameAddr, mir_inst.data.ax.payload).data;
1379 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{
1380 .base = .{ .frame = frame_addr.index },
1381 .disp = frame_addr.off,
1382 }) };
1383 try writer.print(" {}, {}", .{ mir_inst.data.ax.air_inst, mem_op.fmt(.m) });
1384 },
1385 .pseudo_dbg_local_am => {
1386 const mem_op: encoder.Instruction.Operand = .{1247 const mem_op: encoder.Instruction.Operand = .{
1387 .mem = lower.mir.extraData(Mir.Memory, mir_inst.data.ax.payload).data.decode(),1248 .mem = lower.mir.extraData(Mir.Memory, mir_inst.data.x.payload).data.decode(),
1388 };1249 };
1389 try writer.print(" {}, {}", .{ mir_inst.data.ax.air_inst, mem_op.fmt(.m) });1250 try writer.print(" {}", .{mem_op.fmt(.m)});
1390 },1251 },
1252 .pseudo_dbg_arg_val, .pseudo_dbg_var_val => try writer.print(" {}", .{
1253 Value.fromInterned(mir_inst.data.ip_index).fmtValue(data.self.pt),
1254 }),
1391 }1255 }
1392 }1256 }
1393}1257}
...@@ -1440,6 +1304,22 @@ fn addExtraAssumeCapacity(self: *CodeGen, extra: anytype) u32 {...@@ -1440,6 +1304,22 @@ fn addExtraAssumeCapacity(self: *CodeGen, extra: anytype) u32 {
1440 return result;1304 return result;
1441}1305}
14421306
1307fn addString(cg: *CodeGen, string: []const u8) Allocator.Error!Mir.NullTerminatedString {
1308 try cg.mir_string_bytes.ensureUnusedCapacity(cg.gpa, string.len + 1);
1309 try cg.mir_strings.ensureUnusedCapacityContext(cg.gpa, 1, .{ .bytes = &cg.mir_string_bytes });
1310
1311 const mir_string_gop = cg.mir_strings.getOrPutAssumeCapacityAdapted(
1312 string,
1313 std.hash_map.StringIndexAdapter{ .bytes = &cg.mir_string_bytes },
1314 );
1315 if (!mir_string_gop.found_existing) {
1316 mir_string_gop.key_ptr.* = @intCast(cg.mir_string_bytes.items.len);
1317 cg.mir_string_bytes.appendSliceAssumeCapacity(string);
1318 cg.mir_string_bytes.appendAssumeCapacity(0);
1319 }
1320 return @enumFromInt(mir_string_gop.key_ptr.*);
1321}
1322
1443fn asmOps(self: *CodeGen, tag: Mir.Inst.FixedTag, ops: [4]Operand) !void {1323fn asmOps(self: *CodeGen, tag: Mir.Inst.FixedTag, ops: [4]Operand) !void {
1444 return switch (ops[0]) {1324 return switch (ops[0]) {
1445 .none => self.asmOpOnly(tag),1325 .none => self.asmOpOnly(tag),
...@@ -1678,124 +1558,6 @@ fn asmPlaceholder(self: *CodeGen) !Mir.Inst.Index {...@@ -1678,124 +1558,6 @@ fn asmPlaceholder(self: *CodeGen) !Mir.Inst.Index {
1678 });1558 });
1679}1559}
16801560
1681const MirTagAir = enum { dbg_local };
1682
1683fn asmAir(self: *CodeGen, tag: MirTagAir, inst: Air.Inst.Index) !void {
1684 _ = try self.addInst(.{
1685 .tag = .pseudo,
1686 .ops = switch (tag) {
1687 .dbg_local => .pseudo_dbg_local_a,
1688 },
1689 .data = .{ .a = .{ .air_inst = inst } },
1690 });
1691}
1692
1693fn asmAirImmediate(self: *CodeGen, tag: MirTagAir, inst: Air.Inst.Index, imm: Immediate) !void {
1694 switch (imm) {
1695 .signed => |s| _ = try self.addInst(.{
1696 .tag = .pseudo,
1697 .ops = switch (tag) {
1698 .dbg_local => .pseudo_dbg_local_ai_s,
1699 },
1700 .data = .{ .ai = .{
1701 .air_inst = inst,
1702 .i = @bitCast(s),
1703 } },
1704 }),
1705 .unsigned => |u| _ = if (std.math.cast(u32, u)) |small| try self.addInst(.{
1706 .tag = .pseudo,
1707 .ops = switch (tag) {
1708 .dbg_local => .pseudo_dbg_local_ai_u,
1709 },
1710 .data = .{ .ai = .{
1711 .air_inst = inst,
1712 .i = small,
1713 } },
1714 }) else try self.addInst(.{
1715 .tag = .pseudo,
1716 .ops = switch (tag) {
1717 .dbg_local => .pseudo_dbg_local_ai_64,
1718 },
1719 .data = .{ .ai = .{
1720 .air_inst = inst,
1721 .i = try self.addExtra(Mir.Imm64.encode(u)),
1722 } },
1723 }),
1724 .reloc => |sym_off| _ = if (sym_off.off == 0) try self.addInst(.{
1725 .tag = .pseudo,
1726 .ops = switch (tag) {
1727 .dbg_local => .pseudo_dbg_local_as,
1728 },
1729 .data = .{ .as = .{
1730 .air_inst = inst,
1731 .sym_index = sym_off.sym_index,
1732 } },
1733 }) else try self.addInst(.{
1734 .tag = .pseudo,
1735 .ops = switch (tag) {
1736 .dbg_local => .pseudo_dbg_local_aso,
1737 },
1738 .data = .{ .ax = .{
1739 .air_inst = inst,
1740 .payload = try self.addExtra(sym_off),
1741 } },
1742 }),
1743 }
1744}
1745
1746fn asmAirRegisterImmediate(
1747 self: *CodeGen,
1748 tag: MirTagAir,
1749 inst: Air.Inst.Index,
1750 reg: Register,
1751 imm: Immediate,
1752) !void {
1753 _ = try self.addInst(.{
1754 .tag = .pseudo,
1755 .ops = switch (tag) {
1756 .dbg_local => .pseudo_dbg_local_aro,
1757 },
1758 .data = .{ .rx = .{
1759 .r1 = reg,
1760 .payload = try self.addExtra(Mir.AirOffset{
1761 .air_inst = inst,
1762 .off = imm.signed,
1763 }),
1764 } },
1765 });
1766}
1767
1768fn asmAirFrameAddress(
1769 self: *CodeGen,
1770 tag: MirTagAir,
1771 inst: Air.Inst.Index,
1772 frame_addr: bits.FrameAddr,
1773) !void {
1774 _ = try self.addInst(.{
1775 .tag = .pseudo,
1776 .ops = switch (tag) {
1777 .dbg_local => .pseudo_dbg_local_af,
1778 },
1779 .data = .{ .ax = .{
1780 .air_inst = inst,
1781 .payload = try self.addExtra(frame_addr),
1782 } },
1783 });
1784}
1785
1786fn asmAirMemory(self: *CodeGen, tag: MirTagAir, inst: Air.Inst.Index, m: Memory) !void {
1787 _ = try self.addInst(.{
1788 .tag = .pseudo,
1789 .ops = switch (tag) {
1790 .dbg_local => .pseudo_dbg_local_am,
1791 },
1792 .data = .{ .ax = .{
1793 .air_inst = inst,
1794 .payload = try self.addExtra(Mir.Memory.encode(m)),
1795 } },
1796 });
1797}
1798
1799fn asmOpOnly(self: *CodeGen, tag: Mir.Inst.FixedTag) !void {1561fn asmOpOnly(self: *CodeGen, tag: Mir.Inst.FixedTag) !void {
1800 _ = try self.addInst(.{1562 _ = try self.addInst(.{
1801 .tag = tag[1],1563 .tag = tag[1],
...@@ -1873,21 +1635,36 @@ fn asmImmediate(self: *CodeGen, tag: Mir.Inst.FixedTag, imm: Immediate) !void {...@@ -1873,21 +1635,36 @@ fn asmImmediate(self: *CodeGen, tag: Mir.Inst.FixedTag, imm: Immediate) !void {
1873 .ops = switch (imm) {1635 .ops = switch (imm) {
1874 .signed => .i_s,1636 .signed => .i_s,
1875 .unsigned => .i_u,1637 .unsigned => .i_u,
1876 .reloc => .rel,1638 .nav => .nav,
1639 .uav => .uav,
1640 .lazy_sym => .lazy_sym,
1641 .extern_func => .extern_func,
1877 },1642 },
1878 .data = switch (imm) {1643 .data = switch (imm) {
1879 .reloc => |sym_off| reloc: {
1880 assert(tag[0] == ._);
1881 break :reloc .{ .reloc = sym_off };
1882 },
1883 .signed, .unsigned => .{ .i = .{1644 .signed, .unsigned => .{ .i = .{
1884 .fixes = tag[0],1645 .fixes = tag[0],
1885 .i = switch (imm) {1646 .i = switch (imm) {
1886 .signed => |s| @bitCast(s),1647 .signed => |s| @bitCast(s),
1887 .unsigned => |u| @intCast(u),1648 .unsigned => |u| @intCast(u),
1888 .reloc => unreachable,1649 .nav, .uav, .lazy_sym, .extern_func => unreachable,
1889 },1650 },
1890 } },1651 } },
1652 .nav => |nav| switch (tag[0]) {
1653 ._ => .{ .nav = nav },
1654 else => unreachable,
1655 },
1656 .uav => |uav| switch (tag[0]) {
1657 ._ => .{ .uav = uav },
1658 else => unreachable,
1659 },
1660 .lazy_sym => |lazy_sym| switch (tag[0]) {
1661 ._ => .{ .lazy_sym = lazy_sym },
1662 else => unreachable,
1663 },
1664 .extern_func => |extern_func| switch (tag[0]) {
1665 ._ => .{ .extern_func = extern_func },
1666 else => unreachable,
1667 },
1891 },1668 },
1892 });1669 });
1893}1670}
...@@ -1902,7 +1679,7 @@ fn asmImmediateRegister(self: *CodeGen, tag: Mir.Inst.FixedTag, imm: Immediate,...@@ -1902,7 +1679,7 @@ fn asmImmediateRegister(self: *CodeGen, tag: Mir.Inst.FixedTag, imm: Immediate,
1902 .i = @as(u8, switch (imm) {1679 .i = @as(u8, switch (imm) {
1903 .signed => |s| @bitCast(@as(i8, @intCast(s))),1680 .signed => |s| @bitCast(@as(i8, @intCast(s))),
1904 .unsigned => |u| @intCast(u),1681 .unsigned => |u| @intCast(u),
1905 .reloc => unreachable,1682 .nav, .uav, .lazy_sym, .extern_func => unreachable,
1906 }),1683 }),
1907 } },1684 } },
1908 });1685 });
...@@ -1917,12 +1694,12 @@ fn asmImmediateImmediate(self: *CodeGen, tag: Mir.Inst.FixedTag, imm1: Immediate...@@ -1917,12 +1694,12 @@ fn asmImmediateImmediate(self: *CodeGen, tag: Mir.Inst.FixedTag, imm1: Immediate
1917 .i1 = switch (imm1) {1694 .i1 = switch (imm1) {
1918 .signed => |s| @bitCast(@as(i16, @intCast(s))),1695 .signed => |s| @bitCast(@as(i16, @intCast(s))),
1919 .unsigned => |u| @intCast(u),1696 .unsigned => |u| @intCast(u),
1920 .reloc => unreachable,1697 .nav, .uav, .lazy_sym, .extern_func => unreachable,
1921 },1698 },
1922 .i2 = switch (imm2) {1699 .i2 = switch (imm2) {
1923 .signed => |s| @bitCast(@as(i8, @intCast(s))),1700 .signed => |s| @bitCast(@as(i8, @intCast(s))),
1924 .unsigned => |u| @intCast(u),1701 .unsigned => |u| @intCast(u),
1925 .reloc => unreachable,1702 .nav, .uav, .lazy_sym, .extern_func => unreachable,
1926 },1703 },
1927 } },1704 } },
1928 });1705 });
...@@ -1947,7 +1724,7 @@ fn asmRegisterImmediate(self: *CodeGen, tag: Mir.Inst.FixedTag, reg: Register, i...@@ -1947,7 +1724,7 @@ fn asmRegisterImmediate(self: *CodeGen, tag: Mir.Inst.FixedTag, reg: Register, i
1947 .{ .ri_u, small }1724 .{ .ri_u, small }
1948 else1725 else
1949 .{ .ri_64, try self.addExtra(Mir.Imm64.encode(imm.unsigned)) },1726 .{ .ri_64, try self.addExtra(Mir.Imm64.encode(imm.unsigned)) },
1950 .reloc => unreachable,1727 .nav, .uav, .lazy_sym, .extern_func => unreachable,
1951 };1728 };
1952 _ = try self.addInst(.{1729 _ = try self.addInst(.{
1953 .tag = tag[1],1730 .tag = tag[1],
...@@ -2019,7 +1796,7 @@ fn asmRegisterRegisterRegisterImmediate(...@@ -2019,7 +1796,7 @@ fn asmRegisterRegisterRegisterImmediate(
2019 .i = switch (imm) {1796 .i = switch (imm) {
2020 .signed => |s| @bitCast(@as(i8, @intCast(s))),1797 .signed => |s| @bitCast(@as(i8, @intCast(s))),
2021 .unsigned => |u| @intCast(u),1798 .unsigned => |u| @intCast(u),
2022 .reloc => unreachable,1799 .nav, .uav, .lazy_sym, .extern_func => unreachable,
2023 },1800 },
2024 } },1801 } },
2025 });1802 });
...@@ -2037,7 +1814,7 @@ fn asmRegisterRegisterImmediate(...@@ -2037,7 +1814,7 @@ fn asmRegisterRegisterImmediate(
2037 .ops = switch (imm) {1814 .ops = switch (imm) {
2038 .signed => .rri_s,1815 .signed => .rri_s,
2039 .unsigned => .rri_u,1816 .unsigned => .rri_u,
2040 .reloc => unreachable,1817 .nav, .uav, .lazy_sym, .extern_func => unreachable,
2041 },1818 },
2042 .data = .{ .rri = .{1819 .data = .{ .rri = .{
2043 .fixes = tag[0],1820 .fixes = tag[0],
...@@ -2046,7 +1823,7 @@ fn asmRegisterRegisterImmediate(...@@ -2046,7 +1823,7 @@ fn asmRegisterRegisterImmediate(
2046 .i = switch (imm) {1823 .i = switch (imm) {
2047 .signed => |s| @bitCast(s),1824 .signed => |s| @bitCast(s),
2048 .unsigned => |u| @intCast(u),1825 .unsigned => |u| @intCast(u),
2049 .reloc => unreachable,1826 .nav, .uav, .lazy_sym, .extern_func => unreachable,
2050 },1827 },
2051 } },1828 } },
2052 });1829 });
...@@ -2144,7 +1921,7 @@ fn asmRegisterMemoryImmediate(...@@ -2144,7 +1921,7 @@ fn asmRegisterMemoryImmediate(
2144 if (switch (imm) {1921 if (switch (imm) {
2145 .signed => |s| if (std.math.cast(i16, s)) |x| @as(u16, @bitCast(x)) else null,1922 .signed => |s| if (std.math.cast(i16, s)) |x| @as(u16, @bitCast(x)) else null,
2146 .unsigned => |u| std.math.cast(u16, u),1923 .unsigned => |u| std.math.cast(u16, u),
2147 .reloc => unreachable,1924 .nav, .uav, .lazy_sym, .extern_func => unreachable,
2148 }) |small_imm| {1925 }) |small_imm| {
2149 _ = try self.addInst(.{1926 _ = try self.addInst(.{
2150 .tag = tag[1],1927 .tag = tag[1],
...@@ -2160,7 +1937,7 @@ fn asmRegisterMemoryImmediate(...@@ -2160,7 +1937,7 @@ fn asmRegisterMemoryImmediate(
2160 const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) {1937 const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) {
2161 .signed => |s| @bitCast(s),1938 .signed => |s| @bitCast(s),
2162 .unsigned => |u| @as(u32, @intCast(u)),1939 .unsigned => |u| @as(u32, @intCast(u)),
2163 .reloc => unreachable,1940 .nav, .uav, .lazy_sym, .extern_func => unreachable,
2164 } });1941 } });
2165 assert(payload + 1 == try self.addExtra(Mir.Memory.encode(m)));1942 assert(payload + 1 == try self.addExtra(Mir.Memory.encode(m)));
2166 _ = try self.addInst(.{1943 _ = try self.addInst(.{
...@@ -2168,7 +1945,7 @@ fn asmRegisterMemoryImmediate(...@@ -2168,7 +1945,7 @@ fn asmRegisterMemoryImmediate(
2168 .ops = switch (imm) {1945 .ops = switch (imm) {
2169 .signed => .rmi_s,1946 .signed => .rmi_s,
2170 .unsigned => .rmi_u,1947 .unsigned => .rmi_u,
2171 .reloc => unreachable,1948 .nav, .uav, .lazy_sym, .extern_func => unreachable,
2172 },1949 },
2173 .data = .{ .rx = .{1950 .data = .{ .rx = .{
2174 .fixes = tag[0],1951 .fixes = tag[0],
...@@ -2216,7 +1993,7 @@ fn asmMemoryImmediate(self: *CodeGen, tag: Mir.Inst.FixedTag, m: Memory, imm: Im...@@ -2216,7 +1993,7 @@ fn asmMemoryImmediate(self: *CodeGen, tag: Mir.Inst.FixedTag, m: Memory, imm: Im
2216 const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) {1993 const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) {
2217 .signed => |s| @bitCast(s),1994 .signed => |s| @bitCast(s),
2218 .unsigned => |u| @intCast(u),1995 .unsigned => |u| @intCast(u),
2219 .reloc => unreachable,1996 .nav, .uav, .lazy_sym, .extern_func => unreachable,
2220 } });1997 } });
2221 assert(payload + 1 == try self.addExtra(Mir.Memory.encode(m)));1998 assert(payload + 1 == try self.addExtra(Mir.Memory.encode(m)));
2222 _ = try self.addInst(.{1999 _ = try self.addInst(.{
...@@ -2224,7 +2001,7 @@ fn asmMemoryImmediate(self: *CodeGen, tag: Mir.Inst.FixedTag, m: Memory, imm: Im...@@ -2224,7 +2001,7 @@ fn asmMemoryImmediate(self: *CodeGen, tag: Mir.Inst.FixedTag, m: Memory, imm: Im
2224 .ops = switch (imm) {2001 .ops = switch (imm) {
2225 .signed => .mi_s,2002 .signed => .mi_s,
2226 .unsigned => .mi_u,2003 .unsigned => .mi_u,
2227 .reloc => unreachable,2004 .nav, .uav, .lazy_sym, .extern_func => unreachable,
2228 },2005 },
2229 .data = .{ .x = .{2006 .data = .{ .x = .{
2230 .fixes = tag[0],2007 .fixes = tag[0],
...@@ -2271,7 +2048,13 @@ fn asmMemoryRegisterImmediate(...@@ -2271,7 +2048,13 @@ fn asmMemoryRegisterImmediate(
2271 });2048 });
2272}2049}
22732050
2274fn gen(self: *CodeGen) InnerError!void {2051fn gen(
2052 self: *CodeGen,
2053 zir: *const std.zig.Zir,
2054 func_zir_inst: std.zig.Zir.Inst.Index,
2055 comptime_args: InternPool.Index.Slice,
2056 air_arg_count: u32,
2057) InnerError!void {
2275 const pt = self.pt;2058 const pt = self.pt;
2276 const zcu = pt.zcu;2059 const zcu = pt.zcu;
2277 const fn_info = zcu.typeToFunc(self.fn_type).?;2060 const fn_info = zcu.typeToFunc(self.fn_type).?;
...@@ -2339,9 +2122,9 @@ fn gen(self: *CodeGen) InnerError!void {...@@ -2339,9 +2122,9 @@ fn gen(self: *CodeGen) InnerError!void {
2339 else => |cc| return self.fail("{s} does not support var args", .{@tagName(cc)}),2122 else => |cc| return self.fail("{s} does not support var args", .{@tagName(cc)}),
2340 };2123 };
23412124
2342 if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_prologue_end_none);2125 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none);
23432126
2344 try self.genBody(self.air.getMainBody());2127 try self.genMainBody(zir, func_zir_inst, comptime_args, air_arg_count);
23452128
2346 const epilogue = if (self.epilogue_relocs.items.len > 0) epilogue: {2129 const epilogue = if (self.epilogue_relocs.items.len > 0) epilogue: {
2347 var last_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len - 1);2130 var last_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len - 1);
...@@ -2356,7 +2139,7 @@ fn gen(self: *CodeGen) InnerError!void {...@@ -2356,7 +2139,7 @@ fn gen(self: *CodeGen) InnerError!void {
2356 }2139 }
2357 for (self.epilogue_relocs.items) |epilogue_reloc| self.performReloc(epilogue_reloc);2140 for (self.epilogue_relocs.items) |epilogue_reloc| self.performReloc(epilogue_reloc);
23582141
2359 if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);2142 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);
2360 const backpatch_stack_dealloc = try self.asmPlaceholder();2143 const backpatch_stack_dealloc = try self.asmPlaceholder();
2361 const backpatch_pop_callee_preserved_regs = try self.asmPlaceholder();2144 const backpatch_pop_callee_preserved_regs = try self.asmPlaceholder();
2362 try self.asmRegister(.{ ._, .pop }, .rbp);2145 try self.asmRegister(.{ ._, .pop }, .rbp);
...@@ -2475,21 +2258,88 @@ fn gen(self: *CodeGen) InnerError!void {...@@ -2475,21 +2258,88 @@ fn gen(self: *CodeGen) InnerError!void {
2475 });2258 });
2476 }2259 }
2477 } else {2260 } else {
2478 if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_prologue_end_none);2261 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none);
2479 try self.genBody(self.air.getMainBody());2262 try self.genMainBody(zir, func_zir_inst, comptime_args, air_arg_count);
2480 if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);2263 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);
2264 }
2265}
2266
2267fn genMainBody(
2268 cg: *CodeGen,
2269 zir: *const std.zig.Zir,
2270 func_zir_inst: std.zig.Zir.Inst.Index,
2271 comptime_args: InternPool.Index.Slice,
2272 air_arg_count: u32,
2273) InnerError!void {
2274 const pt = cg.pt;
2275 const zcu = pt.zcu;
2276 const ip = &zcu.intern_pool;
2277
2278 const main_body = cg.air.getMainBody();
2279 const air_args_body = main_body[0..air_arg_count];
2280 try cg.genBody(air_args_body);
2281
2282 if (!cg.mod.strip) {
2283 var air_arg_index: usize = 0;
2284 const fn_info = zcu.typeToFunc(cg.fn_type).?;
2285 var fn_param_index: usize = 0;
2286 var zir_param_index: usize = 0;
2287 for (zir.getParamBody(func_zir_inst)) |zir_param_inst| {
2288 const name = switch (zir.getParamName(zir_param_inst) orelse break) {
2289 .empty => .none,
2290 else => |zir_name| try cg.addString(zir.nullTerminatedString(zir_name)),
2291 };
2292 defer zir_param_index += 1;
2293
2294 if (comptime_args.len > 0) switch (comptime_args.get(ip)[zir_param_index]) {
2295 .none => {},
2296 else => |comptime_arg| {
2297 try cg.mir_locals.append(cg.gpa, .{ .name = name, .type = ip.typeOf(comptime_arg) });
2298 _ = try cg.addInst(.{
2299 .tag = .pseudo,
2300 .ops = .pseudo_dbg_arg_val,
2301 .data = .{ .ip_index = comptime_arg },
2302 });
2303 continue;
2304 },
2305 };
2306
2307 const arg_ty = fn_info.param_types.get(ip)[fn_param_index];
2308 try cg.mir_locals.append(cg.gpa, .{ .name = name, .type = arg_ty });
2309 fn_param_index += 1;
2310
2311 if (air_arg_index == air_args_body.len) {
2312 try cg.asmPseudo(.pseudo_dbg_arg_none);
2313 continue;
2314 }
2315 const air_arg_inst = air_args_body[air_arg_index];
2316 const air_arg_data = cg.air.instructions.items(.data)[air_arg_index].arg;
2317 if (air_arg_data.zir_param_index != zir_param_index) {
2318 try cg.asmPseudo(.pseudo_dbg_arg_none);
2319 continue;
2320 }
2321 air_arg_index += 1;
2322 try cg.genLocalDebugInfo(
2323 .arg,
2324 .fromInterned(arg_ty),
2325 cg.getResolvedInstValue(air_arg_inst).short,
2326 );
2327 }
2328 if (fn_info.is_var_args) try cg.asmPseudo(.pseudo_dbg_var_args_none);
2481 }2329 }
2330
2331 try cg.genBody(main_body[air_arg_count..]);
2482}2332}
24832333
2484fn checkInvariantsAfterAirInst(self: *CodeGen) void {2334fn checkInvariantsAfterAirInst(cg: *CodeGen) void {
2485 assert(!self.register_manager.lockedRegsExist());2335 assert(!cg.register_manager.lockedRegsExist());
24862336
2487 if (std.debug.runtime_safety) {2337 if (std.debug.runtime_safety) {
2488 // check consistency of tracked registers2338 // check consistency of tracked registers
2489 var it = self.register_manager.free_registers.iterator(.{ .kind = .unset });2339 var it = cg.register_manager.free_registers.iterator(.{ .kind = .unset });
2490 while (it.next()) |index| {2340 while (it.next()) |index| {
2491 const tracked_inst = self.register_manager.registers[index];2341 const tracked_inst = cg.register_manager.registers[index];
2492 const tracking = self.getResolvedInstValue(tracked_inst);2342 const tracking = cg.getResolvedInstValue(tracked_inst);
2493 for (tracking.getRegs()) |reg| {2343 for (tracking.getRegs()) |reg| {
2494 if (RegisterManager.indexOfRegIntoTracked(reg).? == index) break;2344 if (RegisterManager.indexOfRegIntoTracked(reg).? == index) break;
2495 } else unreachable; // tracked register not in use2345 } else unreachable; // tracked register not in use
...@@ -2497,10 +2347,10 @@ fn checkInvariantsAfterAirInst(self: *CodeGen) void {...@@ -2497,10 +2347,10 @@ fn checkInvariantsAfterAirInst(self: *CodeGen) void {
2497 }2347 }
2498}2348}
24992349
2500fn genBodyBlock(self: *CodeGen, body: []const Air.Inst.Index) InnerError!void {2350fn genBodyBlock(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2501 if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_enter_block_none);2351 if (!cg.mod.strip) try cg.asmPseudo(.pseudo_dbg_enter_block_none);
2502 try self.genBody(body);2352 try cg.genBody(body);
2503 if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_leave_block_none);2353 if (!cg.mod.strip) try cg.asmPseudo(.pseudo_dbg_leave_block_none);
2504}2354}
25052355
2506fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {2356fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
...@@ -2512,25 +2362,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -2512,25 +2362,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2512 const air_datas = cg.air.instructions.items(.data);2362 const air_datas = cg.air.instructions.items(.data);
2513 const use_old = cg.target.ofmt == .coff;2363 const use_old = cg.target.ofmt == .coff;
25142364
2515 cg.arg_index = 0;
2516 for (body) |inst| switch (air_tags[@intFromEnum(inst)]) {
2517 .arg => {
2518 wip_mir_log.debug("{}", .{cg.fmtAir(inst)});
2519 verbose_tracking_log.debug("{}", .{cg.fmtTracking()});
2520
2521 cg.reused_operands = .initEmpty();
2522 try cg.inst_tracking.ensureUnusedCapacity(cg.gpa, 1);
2523
2524 try cg.airArg(inst);
2525
2526 try cg.resetTemps(@enumFromInt(0));
2527 cg.checkInvariantsAfterAirInst();
2528 },
2529 else => break,
2530 };
2531
2532 if (cg.arg_index == 0) try cg.airDbgVarArgs();
2533 cg.arg_index = 0;
2534 for (body) |inst| {2365 for (body) |inst| {
2535 if (cg.liveness.isUnused(inst) and !cg.air.mustLower(inst, ip)) continue;2366 if (cg.liveness.isUnused(inst) and !cg.air.mustLower(inst, ip)) continue;
2536 wip_mir_log.debug("{}", .{cg.fmtAir(inst)});2367 wip_mir_log.debug("{}", .{cg.fmtAir(inst)});
...@@ -2544,20 +2375,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -2544,20 +2375,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2544 .shuffle_one, .shuffle_two => @panic("x86_64 TODO: shuffle_one/shuffle_two"),2375 .shuffle_one, .shuffle_two => @panic("x86_64 TODO: shuffle_one/shuffle_two"),
2545 // zig fmt: on2376 // zig fmt: on
25462377
2547 .arg => if (cg.debug_output != .none) {2378 .arg => try cg.airArg(inst),
2548 // skip zero-bit arguments as they don't have a corresponding arg instruction
2549 var arg_index = cg.arg_index;
2550 while (cg.args[arg_index] == .none) arg_index += 1;
2551 cg.arg_index = arg_index + 1;
2552
2553 const name = air_datas[@intFromEnum(inst)].arg.name;
2554 if (name != .none) try cg.genLocalDebugInfo(inst, cg.getResolvedInstValue(inst).short);
2555 if (cg.liveness.isUnused(inst)) try cg.processDeath(inst);
2556
2557 for (cg.args[arg_index + 1 ..]) |arg| {
2558 if (arg != .none) break;
2559 } else try cg.airDbgVarArgs();
2560 },
2561 .add, .add_optimized, .add_wrap => |air_tag| if (use_old) try cg.airBinOp(inst, switch (air_tag) {2379 .add, .add_optimized, .add_wrap => |air_tag| if (use_old) try cg.airBinOp(inst, switch (air_tag) {
2562 else => unreachable,2380 else => unreachable,
2563 .add, .add_optimized => .add,2381 .add, .add_optimized => .add,
...@@ -3577,7 +3395,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -3577,7 +3395,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3577 },3395 },
3578 .call_frame = .{ .alignment = .@"16" },3396 .call_frame = .{ .alignment = .@"16" },
3579 .extra_temps = .{3397 .extra_temps = .{
3580 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },3398 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
3581 .unused,3399 .unused,
3582 .unused,3400 .unused,
3583 .unused,3401 .unused,
...@@ -3709,7 +3527,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -3709,7 +3527,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3709 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },3527 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
3710 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },3528 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
3711 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },3529 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
3712 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },3530 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
3713 .unused,3531 .unused,
3714 .unused,3532 .unused,
3715 .unused,3533 .unused,
...@@ -3745,7 +3563,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -3745,7 +3563,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3745 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },3563 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
3746 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },3564 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
3747 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },3565 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
3748 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },3566 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
3749 .unused,3567 .unused,
3750 .unused,3568 .unused,
3751 .unused,3569 .unused,
...@@ -3782,7 +3600,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -3782,7 +3600,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3782 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },3600 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
3783 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },3601 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
3784 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },3602 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
3785 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },3603 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
3786 .{ .type = .f16, .kind = .{ .reg = .ax } },3604 .{ .type = .f16, .kind = .{ .reg = .ax } },
3787 .unused,3605 .unused,
3788 .unused,3606 .unused,
...@@ -3822,7 +3640,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -3822,7 +3640,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3822 .{ .type = .f32, .kind = .mem },3640 .{ .type = .f32, .kind = .mem },
3823 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },3641 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
3824 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },3642 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
3825 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },3643 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
3826 .unused,3644 .unused,
3827 .unused,3645 .unused,
3828 .unused,3646 .unused,
...@@ -4307,7 +4125,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -4307,7 +4125,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4307 },4125 },
4308 .call_frame = .{ .alignment = .@"16" },4126 .call_frame = .{ .alignment = .@"16" },
4309 .extra_temps = .{4127 .extra_temps = .{
4310 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },4128 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
4311 .unused,4129 .unused,
4312 .unused,4130 .unused,
4313 .unused,4131 .unused,
...@@ -4339,7 +4157,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -4339,7 +4157,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4339 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },4157 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
4340 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },4158 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
4341 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },4159 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
4342 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },4160 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
4343 .unused,4161 .unused,
4344 .unused,4162 .unused,
4345 .unused,4163 .unused,
...@@ -4374,7 +4192,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -4374,7 +4192,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4374 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },4192 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
4375 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },4193 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
4376 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },4194 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
4377 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },4195 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
4378 .unused,4196 .unused,
4379 .unused,4197 .unused,
4380 .unused,4198 .unused,
...@@ -4409,7 +4227,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -4409,7 +4227,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4409 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },4227 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
4410 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },4228 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
4411 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },4229 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
4412 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },4230 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
4413 .unused,4231 .unused,
4414 .unused,4232 .unused,
4415 .unused,4233 .unused,
...@@ -14009,7 +13827,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -14009,7 +13827,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
14009 },13827 },
14010 .call_frame = .{ .alignment = .@"16" },13828 .call_frame = .{ .alignment = .@"16" },
14011 .extra_temps = .{13829 .extra_temps = .{
14012 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__subhf3" } } },13830 .{ .type = .usize, .kind = .{ .extern_func = "__subhf3" } },
14013 .unused,13831 .unused,
14014 .unused,13832 .unused,
14015 .unused,13833 .unused,
...@@ -14141,7 +13959,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -14141,7 +13959,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
14141 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },13959 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
14142 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },13960 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
14143 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },13961 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
14144 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__subhf3" } } },13962 .{ .type = .usize, .kind = .{ .extern_func = "__subhf3" } },
14145 .unused,13963 .unused,
14146 .unused,13964 .unused,
14147 .unused,13965 .unused,
...@@ -14177,7 +13995,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -14177,7 +13995,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
14177 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },13995 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
14178 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },13996 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
14179 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },13997 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
14180 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__subhf3" } } },13998 .{ .type = .usize, .kind = .{ .extern_func = "__subhf3" } },
14181 .unused,13999 .unused,
14182 .unused,14000 .unused,
14183 .unused,14001 .unused,
...@@ -14214,7 +14032,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -14214,7 +14032,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
14214 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },14032 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
14215 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },14033 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
14216 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },14034 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
14217 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__subhf3" } } },14035 .{ .type = .usize, .kind = .{ .extern_func = "__subhf3" } },
14218 .{ .type = .f16, .kind = .{ .reg = .ax } },14036 .{ .type = .f16, .kind = .{ .reg = .ax } },
14219 .unused,14037 .unused,
14220 .unused,14038 .unused,
...@@ -14254,7 +14072,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -14254,7 +14072,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
14254 .{ .type = .f32, .kind = .mem },14072 .{ .type = .f32, .kind = .mem },
14255 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },14073 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
14256 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },14074 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
14257 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__subhf3" } } },14075 .{ .type = .usize, .kind = .{ .extern_func = "__subhf3" } },
14258 .unused,14076 .unused,
14259 .unused,14077 .unused,
14260 .unused,14078 .unused,
...@@ -14756,7 +14574,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -14756,7 +14574,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
14756 },14574 },
14757 .call_frame = .{ .alignment = .@"16" },14575 .call_frame = .{ .alignment = .@"16" },
14758 .extra_temps = .{14576 .extra_temps = .{
14759 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__subtf3" } } },14577 .{ .type = .usize, .kind = .{ .extern_func = "__subtf3" } },
14760 .unused,14578 .unused,
14761 .unused,14579 .unused,
14762 .unused,14580 .unused,
...@@ -14788,7 +14606,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -14788,7 +14606,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
14788 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },14606 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
14789 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },14607 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
14790 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },14608 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
14791 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__subtf3" } } },14609 .{ .type = .usize, .kind = .{ .extern_func = "__subtf3" } },
14792 .unused,14610 .unused,
14793 .unused,14611 .unused,
14794 .unused,14612 .unused,
...@@ -14823,7 +14641,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -14823,7 +14641,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
14823 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },14641 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
14824 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },14642 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
14825 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },14643 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
14826 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__subtf3" } } },14644 .{ .type = .usize, .kind = .{ .extern_func = "__subtf3" } },
14827 .unused,14645 .unused,
14828 .unused,14646 .unused,
14829 .unused,14647 .unused,
...@@ -14858,7 +14676,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -14858,7 +14676,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
14858 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },14676 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
14859 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },14677 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
14860 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },14678 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
14861 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__subtf3" } } },14679 .{ .type = .usize, .kind = .{ .extern_func = "__subtf3" } },
14862 .unused,14680 .unused,
14863 .unused,14681 .unused,
14864 .unused,14682 .unused,
...@@ -23539,7 +23357,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -23539,7 +23357,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
23539 },23357 },
23540 .call_frame = .{ .alignment = .@"16" },23358 .call_frame = .{ .alignment = .@"16" },
23541 .extra_temps = .{23359 .extra_temps = .{
23542 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },23360 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
23543 .unused,23361 .unused,
23544 .unused,23362 .unused,
23545 .unused,23363 .unused,
...@@ -23671,7 +23489,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -23671,7 +23489,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
23671 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },23489 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
23672 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },23490 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
23673 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },23491 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
23674 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },23492 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
23675 .unused,23493 .unused,
23676 .unused,23494 .unused,
23677 .unused,23495 .unused,
...@@ -23707,7 +23525,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -23707,7 +23525,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
23707 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },23525 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
23708 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },23526 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
23709 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },23527 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
23710 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },23528 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
23711 .unused,23529 .unused,
23712 .unused,23530 .unused,
23713 .unused,23531 .unused,
...@@ -23744,7 +23562,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -23744,7 +23562,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
23744 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },23562 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
23745 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },23563 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
23746 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },23564 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
23747 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },23565 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
23748 .{ .type = .f16, .kind = .{ .reg = .ax } },23566 .{ .type = .f16, .kind = .{ .reg = .ax } },
23749 .unused,23567 .unused,
23750 .unused,23568 .unused,
...@@ -23784,7 +23602,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -23784,7 +23602,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
23784 .{ .type = .f32, .kind = .mem },23602 .{ .type = .f32, .kind = .mem },
23785 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },23603 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
23786 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },23604 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
23787 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },23605 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
23788 .unused,23606 .unused,
23789 .unused,23607 .unused,
23790 .unused,23608 .unused,
...@@ -24269,7 +24087,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -24269,7 +24087,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
24269 },24087 },
24270 .call_frame = .{ .alignment = .@"16" },24088 .call_frame = .{ .alignment = .@"16" },
24271 .extra_temps = .{24089 .extra_temps = .{
24272 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },24090 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
24273 .unused,24091 .unused,
24274 .unused,24092 .unused,
24275 .unused,24093 .unused,
...@@ -24301,7 +24119,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -24301,7 +24119,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
24301 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },24119 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
24302 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },24120 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
24303 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },24121 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
24304 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },24122 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
24305 .unused,24123 .unused,
24306 .unused,24124 .unused,
24307 .unused,24125 .unused,
...@@ -24336,7 +24154,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -24336,7 +24154,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
24336 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },24154 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
24337 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },24155 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
24338 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },24156 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
24339 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },24157 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
24340 .unused,24158 .unused,
24341 .unused,24159 .unused,
24342 .unused,24160 .unused,
...@@ -24371,7 +24189,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -24371,7 +24189,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
24371 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },24189 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
24372 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },24190 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
24373 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },24191 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
24374 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },24192 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
24375 .unused,24193 .unused,
24376 .unused,24194 .unused,
24377 .unused,24195 .unused,
...@@ -26231,7 +26049,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -26231,7 +26049,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
26231 },26049 },
26232 .call_frame = .{ .alignment = .@"16" },26050 .call_frame = .{ .alignment = .@"16" },
26233 .extra_temps = .{26051 .extra_temps = .{
26234 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },26052 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
26235 .unused,26053 .unused,
26236 .unused,26054 .unused,
26237 .unused,26055 .unused,
...@@ -26363,7 +26181,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -26363,7 +26181,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
26363 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },26181 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
26364 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },26182 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
26365 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },26183 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
26366 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },26184 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
26367 .unused,26185 .unused,
26368 .unused,26186 .unused,
26369 .unused,26187 .unused,
...@@ -26399,7 +26217,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -26399,7 +26217,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
26399 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },26217 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
26400 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },26218 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
26401 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },26219 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
26402 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },26220 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
26403 .unused,26221 .unused,
26404 .unused,26222 .unused,
26405 .unused,26223 .unused,
...@@ -26436,7 +26254,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -26436,7 +26254,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
26436 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },26254 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
26437 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },26255 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
26438 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },26256 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
26439 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },26257 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
26440 .{ .type = .f16, .kind = .{ .reg = .ax } },26258 .{ .type = .f16, .kind = .{ .reg = .ax } },
26441 .unused,26259 .unused,
26442 .unused,26260 .unused,
...@@ -26476,7 +26294,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -26476,7 +26294,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
26476 .{ .type = .f32, .kind = .mem },26294 .{ .type = .f32, .kind = .mem },
26477 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },26295 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
26478 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },26296 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
26479 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },26297 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
26480 .unused,26298 .unused,
26481 .unused,26299 .unused,
26482 .unused,26300 .unused,
...@@ -26961,7 +26779,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -26961,7 +26779,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
26961 },26779 },
26962 .call_frame = .{ .alignment = .@"16" },26780 .call_frame = .{ .alignment = .@"16" },
26963 .extra_temps = .{26781 .extra_temps = .{
26964 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },26782 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
26965 .unused,26783 .unused,
26966 .unused,26784 .unused,
26967 .unused,26785 .unused,
...@@ -26993,7 +26811,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -26993,7 +26811,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
26993 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },26811 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
26994 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },26812 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
26995 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },26813 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
26996 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },26814 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
26997 .unused,26815 .unused,
26998 .unused,26816 .unused,
26999 .unused,26817 .unused,
...@@ -27028,7 +26846,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -27028,7 +26846,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
27028 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },26846 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
27029 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },26847 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
27030 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },26848 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
27031 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },26849 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
27032 .unused,26850 .unused,
27033 .unused,26851 .unused,
27034 .unused,26852 .unused,
...@@ -27063,7 +26881,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -27063,7 +26881,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
27063 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },26881 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
27064 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },26882 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
27065 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },26883 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
27066 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },26884 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
27067 .unused,26885 .unused,
27068 .unused,26886 .unused,
27069 .unused,26887 .unused,
...@@ -32371,7 +32189,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -32371,7 +32189,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
32371 },32189 },
32372 .call_frame = .{ .alignment = .@"16" },32190 .call_frame = .{ .alignment = .@"16" },
32373 .extra_temps = .{32191 .extra_temps = .{
32374 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },32192 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
32375 .unused,32193 .unused,
32376 .unused,32194 .unused,
32377 .unused,32195 .unused,
...@@ -32503,7 +32321,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -32503,7 +32321,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
32503 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },32321 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
32504 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },32322 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
32505 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },32323 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
32506 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },32324 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
32507 .unused,32325 .unused,
32508 .unused,32326 .unused,
32509 .unused,32327 .unused,
...@@ -32539,7 +32357,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -32539,7 +32357,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
32539 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },32357 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
32540 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },32358 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
32541 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },32359 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
32542 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },32360 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
32543 .unused,32361 .unused,
32544 .unused,32362 .unused,
32545 .unused,32363 .unused,
...@@ -32576,7 +32394,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -32576,7 +32394,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
32576 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },32394 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
32577 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },32395 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
32578 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },32396 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
32579 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },32397 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
32580 .{ .type = .f16, .kind = .{ .reg = .ax } },32398 .{ .type = .f16, .kind = .{ .reg = .ax } },
32581 .unused,32399 .unused,
32582 .unused,32400 .unused,
...@@ -32616,7 +32434,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -32616,7 +32434,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
32616 .{ .type = .f32, .kind = .mem },32434 .{ .type = .f32, .kind = .mem },
32617 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },32435 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
32618 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },32436 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
32619 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },32437 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
32620 .unused,32438 .unused,
32621 .unused,32439 .unused,
32622 .unused,32440 .unused,
...@@ -33119,7 +32937,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33119,7 +32937,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33119 },32937 },
33120 .call_frame = .{ .alignment = .@"16" },32938 .call_frame = .{ .alignment = .@"16" },
33121 .extra_temps = .{32939 .extra_temps = .{
33122 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },32940 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
33123 .unused,32941 .unused,
33124 .unused,32942 .unused,
33125 .unused,32943 .unused,
...@@ -33151,7 +32969,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33151,7 +32969,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33151 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },32969 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
33152 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },32970 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
33153 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },32971 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
33154 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },32972 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
33155 .unused,32973 .unused,
33156 .unused,32974 .unused,
33157 .unused,32975 .unused,
...@@ -33186,7 +33004,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33186,7 +33004,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33186 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },33004 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
33187 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },33005 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
33188 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },33006 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
33189 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },33007 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
33190 .unused,33008 .unused,
33191 .unused,33009 .unused,
33192 .unused,33010 .unused,
...@@ -33221,7 +33039,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33221,7 +33039,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33221 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },33039 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
33222 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },33040 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
33223 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },33041 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
33224 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },33042 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
33225 .unused,33043 .unused,
33226 .unused,33044 .unused,
33227 .unused,33045 .unused,
...@@ -33305,8 +33123,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33305,8 +33123,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33305 },33123 },
33306 .call_frame = .{ .alignment = .@"16" },33124 .call_frame = .{ .alignment = .@"16" },
33307 .extra_temps = .{33125 .extra_temps = .{
33308 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },33126 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
33309 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunch" } } },33127 .{ .type = .usize, .kind = .{ .extern_func = "__trunch" } },
33310 .unused,33128 .unused,
33311 .unused,33129 .unused,
33312 .unused,33130 .unused,
...@@ -33447,8 +33265,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33447,8 +33265,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33447 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },33265 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
33448 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },33266 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
33449 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },33267 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
33450 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },33268 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
33451 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunch" } } },33269 .{ .type = .usize, .kind = .{ .extern_func = "__trunch" } },
33452 .unused,33270 .unused,
33453 .unused,33271 .unused,
33454 .unused,33272 .unused,
...@@ -33484,8 +33302,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33484,8 +33302,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33484 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },33302 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
33485 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },33303 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
33486 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },33304 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
33487 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },33305 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
33488 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunch" } } },33306 .{ .type = .usize, .kind = .{ .extern_func = "__trunch" } },
33489 .unused,33307 .unused,
33490 .unused,33308 .unused,
33491 .unused,33309 .unused,
...@@ -33522,8 +33340,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33522,8 +33340,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33522 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },33340 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
33523 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },33341 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
33524 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },33342 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
33525 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },33343 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
33526 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunch" } } },33344 .{ .type = .usize, .kind = .{ .extern_func = "__trunch" } },
33527 .{ .type = .f16, .kind = .{ .reg = .ax } },33345 .{ .type = .f16, .kind = .{ .reg = .ax } },
33528 .unused,33346 .unused,
33529 .unused,33347 .unused,
...@@ -33563,8 +33381,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33563,8 +33381,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33563 .{ .type = .f32, .kind = .mem },33381 .{ .type = .f32, .kind = .mem },
33564 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },33382 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
33565 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },33383 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
33566 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },33384 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
33567 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunch" } } },33385 .{ .type = .usize, .kind = .{ .extern_func = "__trunch" } },
33568 .unused,33386 .unused,
33569 .unused,33387 .unused,
33570 .unused,33388 .unused,
...@@ -33632,7 +33450,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33632,7 +33450,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33632 },33450 },
33633 .call_frame = .{ .alignment = .@"16" },33451 .call_frame = .{ .alignment = .@"16" },
33634 .extra_temps = .{33452 .extra_temps = .{
33635 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "truncf" } } },33453 .{ .type = .usize, .kind = .{ .extern_func = "truncf" } },
33636 .unused,33454 .unused,
33637 .unused,33455 .unused,
33638 .unused,33456 .unused,
...@@ -33696,7 +33514,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33696,7 +33514,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33696 .extra_temps = .{33514 .extra_temps = .{
33697 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },33515 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
33698 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },33516 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
33699 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "truncf" } } },33517 .{ .type = .usize, .kind = .{ .extern_func = "truncf" } },
33700 .unused,33518 .unused,
33701 .unused,33519 .unused,
33702 .unused,33520 .unused,
...@@ -33845,7 +33663,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33845,7 +33663,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33845 },33663 },
33846 .call_frame = .{ .alignment = .@"16" },33664 .call_frame = .{ .alignment = .@"16" },
33847 .extra_temps = .{33665 .extra_temps = .{
33848 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "trunc" } } },33666 .{ .type = .usize, .kind = .{ .extern_func = "trunc" } },
33849 .unused,33667 .unused,
33850 .unused,33668 .unused,
33851 .unused,33669 .unused,
...@@ -33875,8 +33693,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33875,8 +33693,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33875 },33693 },
33876 .call_frame = .{ .alignment = .@"16" },33694 .call_frame = .{ .alignment = .@"16" },
33877 .extra_temps = .{33695 .extra_temps = .{
33878 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divdf3" } } },33696 .{ .type = .usize, .kind = .{ .extern_func = "__divdf3" } },
33879 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "trunc" } } },33697 .{ .type = .usize, .kind = .{ .extern_func = "trunc" } },
33880 .unused,33698 .unused,
33881 .unused,33699 .unused,
33882 .unused,33700 .unused,
...@@ -34023,7 +33841,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34023,7 +33841,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34023 .extra_temps = .{33841 .extra_temps = .{
34024 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },33842 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
34025 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },33843 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
34026 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "trunc" } } },33844 .{ .type = .usize, .kind = .{ .extern_func = "trunc" } },
34027 .unused,33845 .unused,
34028 .unused,33846 .unused,
34029 .unused,33847 .unused,
...@@ -34059,8 +33877,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34059,8 +33877,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34059 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },33877 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
34060 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },33878 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
34061 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },33879 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
34062 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divdf3" } } },33880 .{ .type = .usize, .kind = .{ .extern_func = "__divdf3" } },
34063 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "trunc" } } },33881 .{ .type = .usize, .kind = .{ .extern_func = "trunc" } },
34064 .unused,33882 .unused,
34065 .unused,33883 .unused,
34066 .unused,33884 .unused,
...@@ -34097,7 +33915,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34097,7 +33915,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34097 .{ .type = .f80, .kind = .{ .reg = .st6 } },33915 .{ .type = .f80, .kind = .{ .reg = .st6 } },
34098 .{ .type = .f80, .kind = .{ .reg = .st7 } },33916 .{ .type = .f80, .kind = .{ .reg = .st7 } },
34099 .{ .type = .f80, .kind = .{ .frame = .call_frame } },33917 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
34100 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncx" } } },33918 .{ .type = .usize, .kind = .{ .extern_func = "__truncx" } },
34101 .unused,33919 .unused,
34102 .unused,33920 .unused,
34103 .unused,33921 .unused,
...@@ -34131,7 +33949,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34131,7 +33949,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34131 .{ .type = .f80, .kind = .{ .reg = .st6 } },33949 .{ .type = .f80, .kind = .{ .reg = .st6 } },
34132 .{ .type = .f80, .kind = .{ .reg = .st7 } },33950 .{ .type = .f80, .kind = .{ .reg = .st7 } },
34133 .{ .type = .f80, .kind = .{ .frame = .call_frame } },33951 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
34134 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncx" } } },33952 .{ .type = .usize, .kind = .{ .extern_func = "__truncx" } },
34135 .unused,33953 .unused,
34136 .unused,33954 .unused,
34137 .unused,33955 .unused,
...@@ -34165,8 +33983,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34165,8 +33983,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34165 },33983 },
34166 .call_frame = .{ .alignment = .@"16" },33984 .call_frame = .{ .alignment = .@"16" },
34167 .extra_temps = .{33985 .extra_temps = .{
34168 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },33986 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34169 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "truncq" } } },33987 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },
34170 .unused,33988 .unused,
34171 .unused,33989 .unused,
34172 .unused,33990 .unused,
...@@ -34198,8 +34016,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34198,8 +34016,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34198 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },34016 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
34199 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },34017 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
34200 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },34018 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
34201 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },34019 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34202 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "truncq" } } },34020 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },
34203 .unused,34021 .unused,
34204 .unused,34022 .unused,
34205 .unused,34023 .unused,
...@@ -34234,8 +34052,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34234,8 +34052,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34234 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },34052 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
34235 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },34053 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
34236 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },34054 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
34237 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },34055 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34238 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "truncq" } } },34056 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },
34239 .unused,34057 .unused,
34240 .unused,34058 .unused,
34241 .unused,34059 .unused,
...@@ -34270,8 +34088,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34270,8 +34088,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34270 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },34088 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
34271 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },34089 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
34272 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },34090 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
34273 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },34091 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34274 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "truncq" } } },34092 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },
34275 .unused,34093 .unused,
34276 .unused,34094 .unused,
34277 .unused,34095 .unused,
...@@ -34361,12 +34179,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34361,12 +34179,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34361 },34179 },
34362 .call_frame = .{ .alignment = .@"16" },34180 .call_frame = .{ .alignment = .@"16" },
34363 .extra_temps = .{34181 .extra_temps = .{
34364 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },34182 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
34365 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {34183 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
34366 else => unreachable,34184 else => unreachable,
34367 .zero => "__trunch",34185 .zero => "__trunch",
34368 .down => "__floorh",34186 .down => "__floorh",
34369 } } } },34187 } } },
34370 .unused,34188 .unused,
34371 .unused,34189 .unused,
34372 .unused,34190 .unused,
...@@ -34501,12 +34319,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34501,12 +34319,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34501 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },34319 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
34502 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },34320 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
34503 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },34321 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
34504 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },34322 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
34505 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {34323 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
34506 else => unreachable,34324 else => unreachable,
34507 .zero => "__trunch",34325 .zero => "__trunch",
34508 .down => "__floorh",34326 .down => "__floorh",
34509 } } } },34327 } } },
34510 .unused,34328 .unused,
34511 .unused,34329 .unused,
34512 .unused,34330 .unused,
...@@ -34542,12 +34360,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34542,12 +34360,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34542 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },34360 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
34543 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },34361 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
34544 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },34362 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
34545 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },34363 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
34546 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {34364 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
34547 else => unreachable,34365 else => unreachable,
34548 .zero => "__trunch",34366 .zero => "__trunch",
34549 .down => "__floorh",34367 .down => "__floorh",
34550 } } } },34368 } } },
34551 .unused,34369 .unused,
34552 .unused,34370 .unused,
34553 .unused,34371 .unused,
...@@ -34584,12 +34402,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34584,12 +34402,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34584 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },34402 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
34585 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },34403 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
34586 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },34404 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
34587 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },34405 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
34588 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {34406 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
34589 else => unreachable,34407 else => unreachable,
34590 .zero => "__trunch",34408 .zero => "__trunch",
34591 .down => "__floorh",34409 .down => "__floorh",
34592 } } } },34410 } } },
34593 .{ .type = .f16, .kind = .{ .reg = .ax } },34411 .{ .type = .f16, .kind = .{ .reg = .ax } },
34594 .unused,34412 .unused,
34595 .unused,34413 .unused,
...@@ -34629,12 +34447,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34629,12 +34447,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34629 .{ .type = .f32, .kind = .mem },34447 .{ .type = .f32, .kind = .mem },
34630 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },34448 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
34631 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },34449 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
34632 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },34450 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
34633 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {34451 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
34634 else => unreachable,34452 else => unreachable,
34635 .zero => "__trunch",34453 .zero => "__trunch",
34636 .down => "__floorh",34454 .down => "__floorh",
34637 } } } },34455 } } },
34638 .unused,34456 .unused,
34639 .unused,34457 .unused,
34640 .unused,34458 .unused,
...@@ -34702,11 +34520,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34702,11 +34520,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34702 },34520 },
34703 .call_frame = .{ .alignment = .@"16" },34521 .call_frame = .{ .alignment = .@"16" },
34704 .extra_temps = .{34522 .extra_temps = .{
34705 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {34523 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
34706 else => unreachable,34524 else => unreachable,
34707 .zero => "truncf",34525 .zero => "truncf",
34708 .down => "floorf",34526 .down => "floorf",
34709 } } } },34527 } } },
34710 .unused,34528 .unused,
34711 .unused,34529 .unused,
34712 .unused,34530 .unused,
...@@ -34770,11 +34588,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34770,11 +34588,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34770 .extra_temps = .{34588 .extra_temps = .{
34771 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },34589 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
34772 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },34590 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
34773 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {34591 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
34774 else => unreachable,34592 else => unreachable,
34775 .zero => "truncf",34593 .zero => "truncf",
34776 .down => "floorf",34594 .down => "floorf",
34777 } } } },34595 } } },
34778 .unused,34596 .unused,
34779 .unused,34597 .unused,
34780 .unused,34598 .unused,
...@@ -34923,11 +34741,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34923,11 +34741,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34923 },34741 },
34924 .call_frame = .{ .alignment = .@"16" },34742 .call_frame = .{ .alignment = .@"16" },
34925 .extra_temps = .{34743 .extra_temps = .{
34926 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {34744 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
34927 else => unreachable,34745 else => unreachable,
34928 .zero => "trunc",34746 .zero => "trunc",
34929 .down => "floor",34747 .down => "floor",
34930 } } } },34748 } } },
34931 .unused,34749 .unused,
34932 .unused,34750 .unused,
34933 .unused,34751 .unused,
...@@ -34957,12 +34775,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34957,12 +34775,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34957 },34775 },
34958 .call_frame = .{ .alignment = .@"16" },34776 .call_frame = .{ .alignment = .@"16" },
34959 .extra_temps = .{34777 .extra_temps = .{
34960 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divdf3" } } },34778 .{ .type = .usize, .kind = .{ .extern_func = "__divdf3" } },
34961 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {34779 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
34962 else => unreachable,34780 else => unreachable,
34963 .zero => "trunc",34781 .zero => "trunc",
34964 .down => "floor",34782 .down => "floor",
34965 } } } },34783 } } },
34966 .unused,34784 .unused,
34967 .unused,34785 .unused,
34968 .unused,34786 .unused,
...@@ -35109,11 +34927,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35109,11 +34927,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35109 .extra_temps = .{34927 .extra_temps = .{
35110 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },34928 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
35111 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },34929 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
35112 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {34930 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35113 else => unreachable,34931 else => unreachable,
35114 .zero => "trunc",34932 .zero => "trunc",
35115 .down => "floor",34933 .down => "floor",
35116 } } } },34934 } } },
35117 .unused,34935 .unused,
35118 .unused,34936 .unused,
35119 .unused,34937 .unused,
...@@ -35149,12 +34967,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35149,12 +34967,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35149 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },34967 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
35150 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },34968 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
35151 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },34969 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
35152 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divdf3" } } },34970 .{ .type = .usize, .kind = .{ .extern_func = "__divdf3" } },
35153 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {34971 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35154 else => unreachable,34972 else => unreachable,
35155 .zero => "trunc",34973 .zero => "trunc",
35156 .down => "floor",34974 .down => "floor",
35157 } } } },34975 } } },
35158 .unused,34976 .unused,
35159 .unused,34977 .unused,
35160 .unused,34978 .unused,
...@@ -35191,11 +35009,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35191,11 +35009,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35191 .{ .type = .f80, .kind = .{ .reg = .st6 } },35009 .{ .type = .f80, .kind = .{ .reg = .st6 } },
35192 .{ .type = .f80, .kind = .{ .reg = .st7 } },35010 .{ .type = .f80, .kind = .{ .reg = .st7 } },
35193 .{ .type = .f80, .kind = .{ .frame = .call_frame } },35011 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
35194 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {35012 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35195 else => unreachable,35013 else => unreachable,
35196 .zero => "__truncx",35014 .zero => "__truncx",
35197 .down => "__floorx",35015 .down => "__floorx",
35198 } } } },35016 } } },
35199 .unused,35017 .unused,
35200 .unused,35018 .unused,
35201 .unused,35019 .unused,
...@@ -35227,11 +35045,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35227,11 +35045,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35227 .extra_temps = .{35045 .extra_temps = .{
35228 .{ .type = .f80, .kind = .{ .reg = .st7 } },35046 .{ .type = .f80, .kind = .{ .reg = .st7 } },
35229 .{ .type = .f80, .kind = .{ .frame = .call_frame } },35047 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
35230 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {35048 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35231 else => unreachable,35049 else => unreachable,
35232 .zero => "__truncx",35050 .zero => "__truncx",
35233 .down => "__floorx",35051 .down => "__floorx",
35234 } } } },35052 } } },
35235 .unused,35053 .unused,
35236 .unused,35054 .unused,
35237 .unused,35055 .unused,
...@@ -35264,11 +35082,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35264,11 +35082,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35264 .extra_temps = .{35082 .extra_temps = .{
35265 .{ .type = .f80, .kind = .{ .reg = .st7 } },35083 .{ .type = .f80, .kind = .{ .reg = .st7 } },
35266 .{ .type = .f80, .kind = .{ .frame = .call_frame } },35084 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
35267 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {35085 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35268 else => unreachable,35086 else => unreachable,
35269 .zero => "__truncx",35087 .zero => "__truncx",
35270 .down => "__floorx",35088 .down => "__floorx",
35271 } } } },35089 } } },
35272 .unused,35090 .unused,
35273 .unused,35091 .unused,
35274 .unused,35092 .unused,
...@@ -35302,11 +35120,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35302,11 +35120,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35302 .{ .type = .f80, .kind = .{ .reg = .st6 } },35120 .{ .type = .f80, .kind = .{ .reg = .st6 } },
35303 .{ .type = .f80, .kind = .{ .reg = .st7 } },35121 .{ .type = .f80, .kind = .{ .reg = .st7 } },
35304 .{ .type = .f80, .kind = .{ .frame = .call_frame } },35122 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
35305 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {35123 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35306 else => unreachable,35124 else => unreachable,
35307 .zero => "__truncx",35125 .zero => "__truncx",
35308 .down => "__floorx",35126 .down => "__floorx",
35309 } } } },35127 } } },
35310 .unused,35128 .unused,
35311 .unused,35129 .unused,
35312 .unused,35130 .unused,
...@@ -35340,12 +35158,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35340,12 +35158,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35340 },35158 },
35341 .call_frame = .{ .alignment = .@"16" },35159 .call_frame = .{ .alignment = .@"16" },
35342 .extra_temps = .{35160 .extra_temps = .{
35343 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },35161 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
35344 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {35162 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35345 else => unreachable,35163 else => unreachable,
35346 .zero => "truncq",35164 .zero => "truncq",
35347 .down => "floorq",35165 .down => "floorq",
35348 } } } },35166 } } },
35349 .unused,35167 .unused,
35350 .unused,35168 .unused,
35351 .unused,35169 .unused,
...@@ -35377,12 +35195,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35377,12 +35195,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35377 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },35195 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
35378 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },35196 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
35379 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },35197 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
35380 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },35198 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
35381 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {35199 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35382 else => unreachable,35200 else => unreachable,
35383 .zero => "truncq",35201 .zero => "truncq",
35384 .down => "floorq",35202 .down => "floorq",
35385 } } } },35203 } } },
35386 .unused,35204 .unused,
35387 .unused,35205 .unused,
35388 .unused,35206 .unused,
...@@ -35417,12 +35235,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35417,12 +35235,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35417 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },35235 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
35418 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },35236 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
35419 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },35237 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
35420 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },35238 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
35421 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {35239 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35422 else => unreachable,35240 else => unreachable,
35423 .zero => "truncq",35241 .zero => "truncq",
35424 .down => "floorq",35242 .down => "floorq",
35425 } } } },35243 } } },
35426 .unused,35244 .unused,
35427 .unused,35245 .unused,
35428 .unused,35246 .unused,
...@@ -35457,12 +35275,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35457,12 +35275,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35457 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },35275 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
35458 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },35276 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
35459 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },35277 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
35460 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },35278 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
35461 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {35279 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35462 else => unreachable,35280 else => unreachable,
35463 .zero => "truncq",35281 .zero => "truncq",
35464 .down => "floorq",35282 .down => "floorq",
35465 } } } },35283 } } },
35466 .unused,35284 .unused,
35467 .unused,35285 .unused,
35468 .unused,35286 .unused,
...@@ -35649,9 +35467,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35649,9 +35467,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35649 .extra_temps = .{35467 .extra_temps = .{
35650 .{ .type = .i128, .kind = .{ .param_gpr_pair = .{ .cc = .ccc, .at = 0 } } },35468 .{ .type = .i128, .kind = .{ .param_gpr_pair = .{ .cc = .ccc, .at = 0 } } },
35651 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },35469 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
35652 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },35470 .{ .type = .usize, .kind = .{ .extern_func = "__modti3" } },
35653 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },35471 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
35654 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divti3" } } },35472 .{ .type = .usize, .kind = .{ .extern_func = "__divti3" } },
35655 .unused,35473 .unused,
35656 .unused,35474 .unused,
35657 .unused,35475 .unused,
...@@ -35700,9 +35518,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35700,9 +35518,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35700 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },35518 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
35701 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },35519 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
35702 .{ .type = .i32, .kind = .{ .rc = .general_purpose } },35520 .{ .type = .i32, .kind = .{ .rc = .general_purpose } },
35703 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divei4" } } },35521 .{ .type = .usize, .kind = .{ .extern_func = "__divei4" } },
35704 .{ .kind = .{ .mem_of_type = .dst0 } },35522 .{ .kind = .{ .mem_of_type = .dst0 } },
35705 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },35523 .{ .type = .usize, .kind = .{ .extern_func = "__modei4" } },
35706 .unused,35524 .unused,
35707 .unused,35525 .unused,
35708 .unused,35526 .unused,
...@@ -35781,8 +35599,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35781,8 +35599,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35781 },35599 },
35782 .call_frame = .{ .alignment = .@"16" },35600 .call_frame = .{ .alignment = .@"16" },
35783 .extra_temps = .{35601 .extra_temps = .{
35784 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },35602 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
35785 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floorh" } } },35603 .{ .type = .usize, .kind = .{ .extern_func = "__floorh" } },
35786 .unused,35604 .unused,
35787 .unused,35605 .unused,
35788 .unused,35606 .unused,
...@@ -35923,8 +35741,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35923,8 +35741,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35923 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },35741 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
35924 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },35742 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
35925 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },35743 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
35926 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },35744 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
35927 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floorh" } } },35745 .{ .type = .usize, .kind = .{ .extern_func = "__floorh" } },
35928 .unused,35746 .unused,
35929 .unused,35747 .unused,
35930 .unused,35748 .unused,
...@@ -35960,8 +35778,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35960,8 +35778,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35960 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },35778 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
35961 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },35779 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
35962 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },35780 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
35963 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },35781 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
35964 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floorh" } } },35782 .{ .type = .usize, .kind = .{ .extern_func = "__floorh" } },
35965 .unused,35783 .unused,
35966 .unused,35784 .unused,
35967 .unused,35785 .unused,
...@@ -35998,8 +35816,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -35998,8 +35816,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
35998 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },35816 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
35999 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },35817 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
36000 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },35818 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
36001 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },35819 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
36002 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floorh" } } },35820 .{ .type = .usize, .kind = .{ .extern_func = "__floorh" } },
36003 .{ .type = .f16, .kind = .{ .reg = .ax } },35821 .{ .type = .f16, .kind = .{ .reg = .ax } },
36004 .unused,35822 .unused,
36005 .unused,35823 .unused,
...@@ -36039,8 +35857,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36039,8 +35857,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36039 .{ .type = .f32, .kind = .mem },35857 .{ .type = .f32, .kind = .mem },
36040 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },35858 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
36041 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },35859 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
36042 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divhf3" } } },35860 .{ .type = .usize, .kind = .{ .extern_func = "__divhf3" } },
36043 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floorh" } } },35861 .{ .type = .usize, .kind = .{ .extern_func = "__floorh" } },
36044 .unused,35862 .unused,
36045 .unused,35863 .unused,
36046 .unused,35864 .unused,
...@@ -36108,7 +35926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36108,7 +35926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36108 },35926 },
36109 .call_frame = .{ .alignment = .@"16" },35927 .call_frame = .{ .alignment = .@"16" },
36110 .extra_temps = .{35928 .extra_temps = .{
36111 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "floorf" } } },35929 .{ .type = .usize, .kind = .{ .extern_func = "floorf" } },
36112 .unused,35930 .unused,
36113 .unused,35931 .unused,
36114 .unused,35932 .unused,
...@@ -36172,7 +35990,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36172,7 +35990,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36172 .extra_temps = .{35990 .extra_temps = .{
36173 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },35991 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
36174 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },35992 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
36175 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "floorf" } } },35993 .{ .type = .usize, .kind = .{ .extern_func = "floorf" } },
36176 .unused,35994 .unused,
36177 .unused,35995 .unused,
36178 .unused,35996 .unused,
...@@ -36321,7 +36139,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36321,7 +36139,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36321 },36139 },
36322 .call_frame = .{ .alignment = .@"16" },36140 .call_frame = .{ .alignment = .@"16" },
36323 .extra_temps = .{36141 .extra_temps = .{
36324 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "floor" } } },36142 .{ .type = .usize, .kind = .{ .extern_func = "floor" } },
36325 .unused,36143 .unused,
36326 .unused,36144 .unused,
36327 .unused,36145 .unused,
...@@ -36351,8 +36169,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36351,8 +36169,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36351 },36169 },
36352 .call_frame = .{ .alignment = .@"16" },36170 .call_frame = .{ .alignment = .@"16" },
36353 .extra_temps = .{36171 .extra_temps = .{
36354 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divdf3" } } },36172 .{ .type = .usize, .kind = .{ .extern_func = "__divdf3" } },
36355 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "floor" } } },36173 .{ .type = .usize, .kind = .{ .extern_func = "floor" } },
36356 .unused,36174 .unused,
36357 .unused,36175 .unused,
36358 .unused,36176 .unused,
...@@ -36499,7 +36317,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36499,7 +36317,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36499 .extra_temps = .{36317 .extra_temps = .{
36500 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },36318 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
36501 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },36319 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
36502 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "floor" } } },36320 .{ .type = .usize, .kind = .{ .extern_func = "floor" } },
36503 .unused,36321 .unused,
36504 .unused,36322 .unused,
36505 .unused,36323 .unused,
...@@ -36535,8 +36353,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36535,8 +36353,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36535 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },36353 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
36536 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },36354 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
36537 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },36355 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
36538 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divdf3" } } },36356 .{ .type = .usize, .kind = .{ .extern_func = "__divdf3" } },
36539 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "floor" } } },36357 .{ .type = .usize, .kind = .{ .extern_func = "floor" } },
36540 .unused,36358 .unused,
36541 .unused,36359 .unused,
36542 .unused,36360 .unused,
...@@ -36573,7 +36391,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36573,7 +36391,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36573 .{ .type = .f80, .kind = .{ .reg = .st6 } },36391 .{ .type = .f80, .kind = .{ .reg = .st6 } },
36574 .{ .type = .f80, .kind = .{ .reg = .st7 } },36392 .{ .type = .f80, .kind = .{ .reg = .st7 } },
36575 .{ .type = .f80, .kind = .{ .frame = .call_frame } },36393 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
36576 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floorx" } } },36394 .{ .type = .usize, .kind = .{ .extern_func = "__floorx" } },
36577 .unused,36395 .unused,
36578 .unused,36396 .unused,
36579 .unused,36397 .unused,
...@@ -36607,7 +36425,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36607,7 +36425,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36607 .{ .type = .f80, .kind = .{ .reg = .st6 } },36425 .{ .type = .f80, .kind = .{ .reg = .st6 } },
36608 .{ .type = .f80, .kind = .{ .reg = .st7 } },36426 .{ .type = .f80, .kind = .{ .reg = .st7 } },
36609 .{ .type = .f80, .kind = .{ .frame = .call_frame } },36427 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
36610 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floorx" } } },36428 .{ .type = .usize, .kind = .{ .extern_func = "__floorx" } },
36611 .unused,36429 .unused,
36612 .unused,36430 .unused,
36613 .unused,36431 .unused,
...@@ -36641,8 +36459,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36641,8 +36459,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36641 },36459 },
36642 .call_frame = .{ .alignment = .@"16" },36460 .call_frame = .{ .alignment = .@"16" },
36643 .extra_temps = .{36461 .extra_temps = .{
36644 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },36462 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
36645 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "floorq" } } },36463 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },
36646 .unused,36464 .unused,
36647 .unused,36465 .unused,
36648 .unused,36466 .unused,
...@@ -36674,8 +36492,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36674,8 +36492,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36674 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },36492 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
36675 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },36493 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
36676 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },36494 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
36677 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },36495 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
36678 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "floorq" } } },36496 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },
36679 .unused,36497 .unused,
36680 .unused,36498 .unused,
36681 .unused,36499 .unused,
...@@ -36710,8 +36528,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36710,8 +36528,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36710 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },36528 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
36711 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },36529 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
36712 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },36530 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
36713 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },36531 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
36714 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "floorq" } } },36532 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },
36715 .unused,36533 .unused,
36716 .unused,36534 .unused,
36717 .unused,36535 .unused,
...@@ -36746,8 +36564,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36746,8 +36564,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36746 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },36564 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
36747 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },36565 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
36748 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },36566 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
36749 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divtf3" } } },36567 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
36750 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "floorq" } } },36568 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },
36751 .unused,36569 .unused,
36752 .unused,36570 .unused,
36753 .unused,36571 .unused,
...@@ -36903,7 +36721,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36903,7 +36721,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36903 },36721 },
36904 .call_frame = .{ .alignment = .@"16" },36722 .call_frame = .{ .alignment = .@"16" },
36905 .extra_temps = .{36723 .extra_temps = .{
36906 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },36724 .{ .type = .usize, .kind = .{ .extern_func = "__modti3" } },
36907 .unused,36725 .unused,
36908 .unused,36726 .unused,
36909 .unused,36727 .unused,
...@@ -36932,7 +36750,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36932,7 +36750,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36932 },36750 },
36933 .call_frame = .{ .alignment = .@"16" },36751 .call_frame = .{ .alignment = .@"16" },
36934 .extra_temps = .{36752 .extra_temps = .{
36935 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodti3" } } },36753 .{ .type = .usize, .kind = .{ .extern_func = "__umodti3" } },
36936 .unused,36754 .unused,
36937 .unused,36755 .unused,
36938 .unused,36756 .unused,
...@@ -36965,7 +36783,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36965,7 +36783,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36965 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },36783 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
36966 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },36784 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
36967 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },36785 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
36968 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },36786 .{ .type = .usize, .kind = .{ .extern_func = "__modei4" } },
36969 .unused,36787 .unused,
36970 .unused,36788 .unused,
36971 .unused,36789 .unused,
...@@ -36998,7 +36816,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36998,7 +36816,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36998 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },36816 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
36999 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },36817 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
37000 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },36818 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
37001 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } },36819 .{ .type = .usize, .kind = .{ .extern_func = "__umodei4" } },
37002 .unused,36820 .unused,
37003 .unused,36821 .unused,
37004 .unused,36822 .unused,
...@@ -37362,7 +37180,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37362,7 +37180,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37362 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },37180 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
37363 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },37181 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
37364 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },37182 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
37365 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },37183 .{ .type = .usize, .kind = .{ .extern_func = "__modti3" } },
37366 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },37184 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },
37367 .unused,37185 .unused,
37368 .unused,37186 .unused,
...@@ -37400,7 +37218,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37400,7 +37218,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37400 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },37218 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
37401 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },37219 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
37402 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },37220 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
37403 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodti3" } } },37221 .{ .type = .usize, .kind = .{ .extern_func = "__umodti3" } },
37404 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },37222 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },
37405 .unused,37223 .unused,
37406 .unused,37224 .unused,
...@@ -37438,7 +37256,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37438,7 +37256,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37438 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },37256 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
37439 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },37257 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
37440 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },37258 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
37441 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },37259 .{ .type = .usize, .kind = .{ .extern_func = "__modei4" } },
37442 .unused,37260 .unused,
37443 .unused,37261 .unused,
37444 .unused,37262 .unused,
...@@ -37474,7 +37292,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37474,7 +37292,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37474 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },37292 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
37475 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },37293 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
37476 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },37294 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
37477 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } },37295 .{ .type = .usize, .kind = .{ .extern_func = "__umodei4" } },
37478 .unused,37296 .unused,
37479 .unused,37297 .unused,
37480 .unused,37298 .unused,
...@@ -37505,7 +37323,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37505,7 +37323,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37505 },37323 },
37506 .call_frame = .{ .alignment = .@"16" },37324 .call_frame = .{ .alignment = .@"16" },
37507 .extra_temps = .{37325 .extra_temps = .{
37508 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },37326 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
37509 .unused,37327 .unused,
37510 .unused,37328 .unused,
37511 .unused,37329 .unused,
...@@ -37537,7 +37355,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37537,7 +37355,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37537 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },37355 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37538 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },37356 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
37539 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },37357 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
37540 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },37358 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
37541 .unused,37359 .unused,
37542 .unused,37360 .unused,
37543 .unused,37361 .unused,
...@@ -37573,7 +37391,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37573,7 +37391,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37573 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },37391 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37574 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },37392 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
37575 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },37393 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
37576 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },37394 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
37577 .unused,37395 .unused,
37578 .unused,37396 .unused,
37579 .unused,37397 .unused,
...@@ -37610,7 +37428,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37610,7 +37428,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37610 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },37428 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37611 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },37429 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
37612 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },37430 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
37613 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },37431 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
37614 .{ .type = .f16, .kind = .{ .reg = .ax } },37432 .{ .type = .f16, .kind = .{ .reg = .ax } },
37615 .unused,37433 .unused,
37616 .unused,37434 .unused,
...@@ -37650,7 +37468,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37650,7 +37468,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37650 .{ .type = .f32, .kind = .mem },37468 .{ .type = .f32, .kind = .mem },
37651 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },37469 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
37652 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },37470 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
37653 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },37471 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
37654 .unused,37472 .unused,
37655 .unused,37473 .unused,
37656 .unused,37474 .unused,
...@@ -37686,7 +37504,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37686,7 +37504,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37686 },37504 },
37687 .call_frame = .{ .alignment = .@"16" },37505 .call_frame = .{ .alignment = .@"16" },
37688 .extra_temps = .{37506 .extra_temps = .{
37689 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodf" } } },37507 .{ .type = .usize, .kind = .{ .extern_func = "fmodf" } },
37690 .unused,37508 .unused,
37691 .unused,37509 .unused,
37692 .unused,37510 .unused,
...@@ -37718,7 +37536,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37718,7 +37536,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37718 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },37536 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37719 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },37537 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
37720 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },37538 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },
37721 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodf" } } },37539 .{ .type = .usize, .kind = .{ .extern_func = "fmodf" } },
37722 .unused,37540 .unused,
37723 .unused,37541 .unused,
37724 .unused,37542 .unused,
...@@ -37753,7 +37571,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37753,7 +37571,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37753 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },37571 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37754 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },37572 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
37755 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },37573 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },
37756 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodf" } } },37574 .{ .type = .usize, .kind = .{ .extern_func = "fmodf" } },
37757 .unused,37575 .unused,
37758 .unused,37576 .unused,
37759 .unused,37577 .unused,
...@@ -37785,7 +37603,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37785,7 +37603,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37785 },37603 },
37786 .call_frame = .{ .alignment = .@"16" },37604 .call_frame = .{ .alignment = .@"16" },
37787 .extra_temps = .{37605 .extra_temps = .{
37788 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmod" } } },37606 .{ .type = .usize, .kind = .{ .extern_func = "fmod" } },
37789 .unused,37607 .unused,
37790 .unused,37608 .unused,
37791 .unused,37609 .unused,
...@@ -37817,7 +37635,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37817,7 +37635,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37817 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },37635 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37818 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },37636 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
37819 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },37637 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
37820 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmod" } } },37638 .{ .type = .usize, .kind = .{ .extern_func = "fmod" } },
37821 .unused,37639 .unused,
37822 .unused,37640 .unused,
37823 .unused,37641 .unused,
...@@ -37852,7 +37670,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37852,7 +37670,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37852 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },37670 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37853 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },37671 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
37854 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },37672 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
37855 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmod" } } },37673 .{ .type = .usize, .kind = .{ .extern_func = "fmod" } },
37856 .unused,37674 .unused,
37857 .unused,37675 .unused,
37858 .unused,37676 .unused,
...@@ -37887,7 +37705,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37887,7 +37705,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37887 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },37705 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37888 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },37706 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
37889 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },37707 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
37890 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmod" } } },37708 .{ .type = .usize, .kind = .{ .extern_func = "fmod" } },
37891 .unused,37709 .unused,
37892 .unused,37710 .unused,
37893 .unused,37711 .unused,
...@@ -37923,7 +37741,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37923,7 +37741,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37923 .extra_temps = .{37741 .extra_temps = .{
37924 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },37742 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
37925 .{ .type = .f80, .kind = .{ .frame = .call_frame } },37743 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
37926 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },37744 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
37927 .unused,37745 .unused,
37928 .unused,37746 .unused,
37929 .unused,37747 .unused,
...@@ -37956,7 +37774,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37956,7 +37774,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37956 .extra_temps = .{37774 .extra_temps = .{
37957 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },37775 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
37958 .{ .type = .f80, .kind = .{ .frame = .call_frame } },37776 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
37959 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },37777 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
37960 .unused,37778 .unused,
37961 .unused,37779 .unused,
37962 .unused,37780 .unused,
...@@ -37989,7 +37807,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37989,7 +37807,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37989 .extra_temps = .{37807 .extra_temps = .{
37990 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },37808 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
37991 .{ .type = .f80, .kind = .{ .frame = .call_frame } },37809 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
37992 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },37810 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
37993 .unused,37811 .unused,
37994 .unused,37812 .unused,
37995 .unused,37813 .unused,
...@@ -38023,7 +37841,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38023,7 +37841,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38023 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },37841 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
38024 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },37842 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
38025 .{ .type = .f80, .kind = .{ .frame = .call_frame } },37843 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
38026 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },37844 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
38027 .unused,37845 .unused,
38028 .unused,37846 .unused,
38029 .unused,37847 .unused,
...@@ -38061,7 +37879,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38061,7 +37879,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38061 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },37879 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
38062 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },37880 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
38063 .{ .type = .f80, .kind = .{ .frame = .call_frame } },37881 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
38064 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },37882 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
38065 .unused,37883 .unused,
38066 .unused,37884 .unused,
38067 .unused,37885 .unused,
...@@ -38099,7 +37917,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38099,7 +37917,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38099 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },37917 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
38100 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },37918 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
38101 .{ .type = .f80, .kind = .{ .frame = .call_frame } },37919 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
38102 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },37920 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
38103 .unused,37921 .unused,
38104 .unused,37922 .unused,
38105 .unused,37923 .unused,
...@@ -38134,7 +37952,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38134,7 +37952,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38134 },37952 },
38135 .call_frame = .{ .alignment = .@"16" },37953 .call_frame = .{ .alignment = .@"16" },
38136 .extra_temps = .{37954 .extra_temps = .{
38137 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodq" } } },37955 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
38138 .unused,37956 .unused,
38139 .unused,37957 .unused,
38140 .unused,37958 .unused,
...@@ -38166,7 +37984,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38166,7 +37984,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38166 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },37984 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
38167 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },37985 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
38168 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },37986 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
38169 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodq" } } },37987 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
38170 .unused,37988 .unused,
38171 .unused,37989 .unused,
38172 .unused,37990 .unused,
...@@ -38201,7 +38019,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38201,7 +38019,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38201 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },38019 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
38202 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },38020 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
38203 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },38021 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
38204 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodq" } } },38022 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
38205 .unused,38023 .unused,
38206 .unused,38024 .unused,
38207 .unused,38025 .unused,
...@@ -38236,7 +38054,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38236,7 +38054,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38236 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },38054 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
38237 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },38055 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
38238 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },38056 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
38239 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodq" } } },38057 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
38240 .unused,38058 .unused,
38241 .unused,38059 .unused,
38242 .unused,38060 .unused,
...@@ -38571,7 +38389,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38571,7 +38389,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38571 .call_frame = .{ .alignment = .@"16" },38389 .call_frame = .{ .alignment = .@"16" },
38572 .extra_temps = .{38390 .extra_temps = .{
38573 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },38391 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
38574 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },38392 .{ .type = .usize, .kind = .{ .extern_func = "__modti3" } },
38575 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },38393 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
38576 .unused,38394 .unused,
38577 .unused,38395 .unused,
...@@ -38610,7 +38428,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38610,7 +38428,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38610 .call_frame = .{ .alignment = .@"16" },38428 .call_frame = .{ .alignment = .@"16" },
38611 .extra_temps = .{38429 .extra_temps = .{
38612 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },38430 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
38613 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },38431 .{ .type = .usize, .kind = .{ .extern_func = "__modti3" } },
38614 .unused,38432 .unused,
38615 .unused,38433 .unused,
38616 .unused,38434 .unused,
...@@ -38650,7 +38468,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38650,7 +38468,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38650 },38468 },
38651 .call_frame = .{ .alignment = .@"16" },38469 .call_frame = .{ .alignment = .@"16" },
38652 .extra_temps = .{38470 .extra_temps = .{
38653 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodti3" } } },38471 .{ .type = .usize, .kind = .{ .extern_func = "__umodti3" } },
38654 .unused,38472 .unused,
38655 .unused,38473 .unused,
38656 .unused,38474 .unused,
...@@ -38684,7 +38502,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38684,7 +38502,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38684 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },38502 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
38685 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },38503 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
38686 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },38504 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
38687 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },38505 .{ .type = .usize, .kind = .{ .extern_func = "__modei4" } },
38688 .unused,38506 .unused,
38689 .unused,38507 .unused,
38690 .unused,38508 .unused,
...@@ -38741,7 +38559,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38741,7 +38559,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38741 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },38559 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
38742 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },38560 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
38743 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },38561 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
38744 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } },38562 .{ .type = .usize, .kind = .{ .extern_func = "__umodei4" } },
38745 .unused,38563 .unused,
38746 .unused,38564 .unused,
38747 .unused,38565 .unused,
...@@ -38771,7 +38589,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38771,7 +38589,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38771 .call_frame = .{ .alignment = .@"16" },38589 .call_frame = .{ .alignment = .@"16" },
38772 .extra_temps = .{38590 .extra_temps = .{
38773 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },38591 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
38774 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },38592 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
38775 .{ .type = .f16, .kind = .{ .reg = .dx } },38593 .{ .type = .f16, .kind = .{ .reg = .dx } },
38776 .{ .type = .f16, .kind = .{ .reg = .ax } },38594 .{ .type = .f16, .kind = .{ .reg = .ax } },
38777 .unused,38595 .unused,
...@@ -38812,7 +38630,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38812,7 +38630,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38812 .call_frame = .{ .alignment = .@"16" },38630 .call_frame = .{ .alignment = .@"16" },
38813 .extra_temps = .{38631 .extra_temps = .{
38814 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },38632 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
38815 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },38633 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
38816 .{ .type = .f16, .kind = .{ .reg = .dx } },38634 .{ .type = .f16, .kind = .{ .reg = .dx } },
38817 .{ .type = .f16, .kind = .{ .reg = .ax } },38635 .{ .type = .f16, .kind = .{ .reg = .ax } },
38818 .unused,38636 .unused,
...@@ -38853,10 +38671,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38853,10 +38671,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38853 .call_frame = .{ .alignment = .@"16" },38671 .call_frame = .{ .alignment = .@"16" },
38854 .extra_temps = .{38672 .extra_temps = .{
38855 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },38673 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
38856 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },38674 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
38857 .{ .type = .f16, .kind = .{ .reg = .dx } },38675 .{ .type = .f16, .kind = .{ .reg = .dx } },
38858 .{ .type = .f16, .kind = .{ .reg = .ax } },38676 .{ .type = .f16, .kind = .{ .reg = .ax } },
38859 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },38677 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
38860 .unused,38678 .unused,
38861 .unused,38679 .unused,
38862 .unused,38680 .unused,
...@@ -38891,10 +38709,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38891,10 +38709,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38891 .call_frame = .{ .alignment = .@"16" },38709 .call_frame = .{ .alignment = .@"16" },
38892 .extra_temps = .{38710 .extra_temps = .{
38893 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },38711 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
38894 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },38712 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
38895 .{ .type = .f16, .kind = .{ .reg = .dx } },38713 .{ .type = .f16, .kind = .{ .reg = .dx } },
38896 .{ .type = .f16, .kind = .{ .reg = .ax } },38714 .{ .type = .f16, .kind = .{ .reg = .ax } },
38897 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },38715 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
38898 .unused,38716 .unused,
38899 .unused,38717 .unused,
38900 .unused,38718 .unused,
...@@ -38929,10 +38747,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38929,10 +38747,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38929 .call_frame = .{ .alignment = .@"16" },38747 .call_frame = .{ .alignment = .@"16" },
38930 .extra_temps = .{38748 .extra_temps = .{
38931 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },38749 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
38932 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },38750 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
38933 .{ .type = .f16, .kind = .{ .reg = .dx } },38751 .{ .type = .f16, .kind = .{ .reg = .dx } },
38934 .{ .type = .f16, .kind = .{ .reg = .ax } },38752 .{ .type = .f16, .kind = .{ .reg = .ax } },
38935 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },38753 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
38936 .unused,38754 .unused,
38937 .unused,38755 .unused,
38938 .unused,38756 .unused,
...@@ -38967,10 +38785,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -38967,10 +38785,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
38967 .call_frame = .{ .alignment = .@"16" },38785 .call_frame = .{ .alignment = .@"16" },
38968 .extra_temps = .{38786 .extra_temps = .{
38969 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },38787 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
38970 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },38788 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
38971 .{ .type = .f16, .kind = .{ .reg = .dx } },38789 .{ .type = .f16, .kind = .{ .reg = .dx } },
38972 .{ .type = .f16, .kind = .{ .reg = .ax } },38790 .{ .type = .f16, .kind = .{ .reg = .ax } },
38973 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },38791 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
38974 .unused,38792 .unused,
38975 .unused,38793 .unused,
38976 .unused,38794 .unused,
...@@ -39005,10 +38823,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39005,10 +38823,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39005 .call_frame = .{ .alignment = .@"16" },38823 .call_frame = .{ .alignment = .@"16" },
39006 .extra_temps = .{38824 .extra_temps = .{
39007 .{ .type = .f32, .kind = .mem },38825 .{ .type = .f32, .kind = .mem },
39008 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },38826 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
39009 .{ .type = .f32, .kind = .mem },38827 .{ .type = .f32, .kind = .mem },
39010 .{ .type = .f16, .kind = .{ .reg = .ax } },38828 .{ .type = .f16, .kind = .{ .reg = .ax } },
39011 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },38829 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
39012 .unused,38830 .unused,
39013 .unused,38831 .unused,
39014 .unused,38832 .unused,
...@@ -39043,10 +38861,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39043,10 +38861,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39043 .call_frame = .{ .alignment = .@"16" },38861 .call_frame = .{ .alignment = .@"16" },
39044 .extra_temps = .{38862 .extra_temps = .{
39045 .{ .type = .f32, .kind = .mem },38863 .{ .type = .f32, .kind = .mem },
39046 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },38864 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
39047 .{ .type = .f32, .kind = .mem },38865 .{ .type = .f32, .kind = .mem },
39048 .{ .type = .f16, .kind = .{ .reg = .ax } },38866 .{ .type = .f16, .kind = .{ .reg = .ax } },
39049 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },38867 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
39050 .unused,38868 .unused,
39051 .unused,38869 .unused,
39052 .unused,38870 .unused,
...@@ -39084,7 +38902,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39084,7 +38902,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39084 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },38902 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
39085 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },38903 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
39086 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },38904 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
39087 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },38905 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
39088 .{ .type = .f16, .kind = .{ .reg = .dx } },38906 .{ .type = .f16, .kind = .{ .reg = .dx } },
39089 .{ .type = .f16, .kind = .{ .reg = .ax } },38907 .{ .type = .f16, .kind = .{ .reg = .ax } },
39090 .unused,38908 .unused,
...@@ -39132,7 +38950,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39132,7 +38950,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39132 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },38950 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
39133 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },38951 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
39134 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },38952 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
39135 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },38953 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
39136 .{ .type = .f16, .kind = .{ .reg = .dx } },38954 .{ .type = .f16, .kind = .{ .reg = .dx } },
39137 .{ .type = .f16, .kind = .{ .reg = .ax } },38955 .{ .type = .f16, .kind = .{ .reg = .ax } },
39138 .unused,38956 .unused,
...@@ -39180,10 +38998,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39180,10 +38998,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39180 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },38998 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
39181 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },38999 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
39182 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },39000 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
39183 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },39001 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
39184 .{ .type = .f16, .kind = .{ .reg = .dx } },39002 .{ .type = .f16, .kind = .{ .reg = .dx } },
39185 .{ .type = .f16, .kind = .{ .reg = .ax } },39003 .{ .type = .f16, .kind = .{ .reg = .ax } },
39186 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },39004 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
39187 .unused,39005 .unused,
39188 .unused,39006 .unused,
39189 .unused,39007 .unused,
...@@ -39225,10 +39043,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39225,10 +39043,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39225 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },39043 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
39226 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },39044 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
39227 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },39045 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
39228 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },39046 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
39229 .{ .type = .f16, .kind = .{ .reg = .dx } },39047 .{ .type = .f16, .kind = .{ .reg = .dx } },
39230 .{ .type = .f16, .kind = .{ .reg = .ax } },39048 .{ .type = .f16, .kind = .{ .reg = .ax } },
39231 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },39049 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
39232 .unused,39050 .unused,
39233 .unused,39051 .unused,
39234 .unused,39052 .unused,
...@@ -39270,10 +39088,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39270,10 +39088,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39270 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },39088 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
39271 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },39089 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
39272 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },39090 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
39273 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },39091 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
39274 .{ .type = .f16, .kind = .{ .reg = .dx } },39092 .{ .type = .f16, .kind = .{ .reg = .dx } },
39275 .{ .type = .f16, .kind = .{ .reg = .ax } },39093 .{ .type = .f16, .kind = .{ .reg = .ax } },
39276 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },39094 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
39277 .unused,39095 .unused,
39278 .unused,39096 .unused,
39279 .unused,39097 .unused,
...@@ -39315,10 +39133,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39315,10 +39133,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39315 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },39133 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
39316 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },39134 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
39317 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },39135 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
39318 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },39136 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
39319 .{ .type = .f16, .kind = .{ .reg = .dx } },39137 .{ .type = .f16, .kind = .{ .reg = .dx } },
39320 .{ .type = .f16, .kind = .{ .reg = .ax } },39138 .{ .type = .f16, .kind = .{ .reg = .ax } },
39321 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },39139 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
39322 .unused,39140 .unused,
39323 .unused,39141 .unused,
39324 .unused,39142 .unused,
...@@ -39360,10 +39178,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39360,10 +39178,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39360 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },39178 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
39361 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },39179 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
39362 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },39180 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
39363 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },39181 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
39364 .{ .type = .f16, .kind = .{ .reg = .dx } },39182 .{ .type = .f16, .kind = .{ .reg = .dx } },
39365 .{ .type = .f16, .kind = .{ .reg = .ax } },39183 .{ .type = .f16, .kind = .{ .reg = .ax } },
39366 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },39184 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
39367 .unused,39185 .unused,
39368 .unused,39186 .unused,
39369 .unused,39187 .unused,
...@@ -39406,10 +39224,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39406,10 +39224,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39406 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },39224 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
39407 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },39225 .{ .type = .f16, .kind = .{ .rc = .general_purpose } },
39408 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },39226 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
39409 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },39227 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
39410 .{ .type = .f16, .kind = .{ .reg = .dx } },39228 .{ .type = .f16, .kind = .{ .reg = .dx } },
39411 .{ .type = .f16, .kind = .{ .reg = .ax } },39229 .{ .type = .f16, .kind = .{ .reg = .ax } },
39412 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },39230 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
39413 .unused,39231 .unused,
39414 .unused,39232 .unused,
39415 .unused,39233 .unused,
...@@ -39453,9 +39271,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39453,9 +39271,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39453 .{ .type = .f32, .kind = .mem },39271 .{ .type = .f32, .kind = .mem },
39454 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },39272 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
39455 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },39273 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
39456 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },39274 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
39457 .{ .type = .f32, .kind = .mem },39275 .{ .type = .f32, .kind = .mem },
39458 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },39276 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
39459 .unused,39277 .unused,
39460 .unused,39278 .unused,
39461 .unused,39279 .unused,
...@@ -39502,9 +39320,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39502,9 +39320,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39502 .{ .type = .f32, .kind = .mem },39320 .{ .type = .f32, .kind = .mem },
39503 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },39321 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
39504 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },39322 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
39505 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodh" } } },39323 .{ .type = .usize, .kind = .{ .extern_func = "__fmodh" } },
39506 .{ .type = .f32, .kind = .mem },39324 .{ .type = .f32, .kind = .mem },
39507 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },39325 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
39508 .unused,39326 .unused,
39509 .unused,39327 .unused,
39510 .unused,39328 .unused,
...@@ -39547,7 +39365,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39547,7 +39365,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39547 .call_frame = .{ .alignment = .@"16" },39365 .call_frame = .{ .alignment = .@"16" },
39548 .extra_temps = .{39366 .extra_temps = .{
39549 .{ .type = .f32, .kind = .{ .rc = .general_purpose } },39367 .{ .type = .f32, .kind = .{ .rc = .general_purpose } },
39550 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodf" } } },39368 .{ .type = .usize, .kind = .{ .extern_func = "fmodf" } },
39551 .{ .type = .f32, .kind = .{ .reg = .edx } },39369 .{ .type = .f32, .kind = .{ .reg = .edx } },
39552 .{ .type = .f32, .kind = .{ .reg = .eax } },39370 .{ .type = .f32, .kind = .{ .reg = .eax } },
39553 .unused,39371 .unused,
...@@ -39585,7 +39403,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39585,7 +39403,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39585 .call_frame = .{ .alignment = .@"16" },39403 .call_frame = .{ .alignment = .@"16" },
39586 .extra_temps = .{39404 .extra_temps = .{
39587 .{ .type = .f32, .kind = .{ .rc = .general_purpose } },39405 .{ .type = .f32, .kind = .{ .rc = .general_purpose } },
39588 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodf" } } },39406 .{ .type = .usize, .kind = .{ .extern_func = "fmodf" } },
39589 .{ .type = .f32, .kind = .{ .reg = .edx } },39407 .{ .type = .f32, .kind = .{ .reg = .edx } },
39590 .{ .type = .f32, .kind = .{ .reg = .eax } },39408 .{ .type = .f32, .kind = .{ .reg = .eax } },
39591 .unused,39409 .unused,
...@@ -39623,7 +39441,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39623,7 +39441,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39623 .call_frame = .{ .alignment = .@"16" },39441 .call_frame = .{ .alignment = .@"16" },
39624 .extra_temps = .{39442 .extra_temps = .{
39625 .{ .type = .f32, .kind = .mem },39443 .{ .type = .f32, .kind = .mem },
39626 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodf" } } },39444 .{ .type = .usize, .kind = .{ .extern_func = "fmodf" } },
39627 .{ .type = .f32, .kind = .mem },39445 .{ .type = .f32, .kind = .mem },
39628 .{ .type = .f32, .kind = .{ .reg = .eax } },39446 .{ .type = .f32, .kind = .{ .reg = .eax } },
39629 .unused,39447 .unused,
...@@ -39663,7 +39481,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39663,7 +39481,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39663 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },39481 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
39664 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },39482 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },
39665 .{ .type = .f32, .kind = .{ .rc = .general_purpose } },39483 .{ .type = .f32, .kind = .{ .rc = .general_purpose } },
39666 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodf" } } },39484 .{ .type = .usize, .kind = .{ .extern_func = "fmodf" } },
39667 .{ .type = .f32, .kind = .{ .reg = .edx } },39485 .{ .type = .f32, .kind = .{ .reg = .edx } },
39668 .{ .type = .f32, .kind = .{ .reg = .eax } },39486 .{ .type = .f32, .kind = .{ .reg = .eax } },
39669 .unused,39487 .unused,
...@@ -39707,7 +39525,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39707,7 +39525,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39707 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },39525 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
39708 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },39526 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },
39709 .{ .type = .f32, .kind = .{ .rc = .general_purpose } },39527 .{ .type = .f32, .kind = .{ .rc = .general_purpose } },
39710 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodf" } } },39528 .{ .type = .usize, .kind = .{ .extern_func = "fmodf" } },
39711 .{ .type = .f32, .kind = .{ .reg = .edx } },39529 .{ .type = .f32, .kind = .{ .reg = .edx } },
39712 .{ .type = .f32, .kind = .{ .reg = .eax } },39530 .{ .type = .f32, .kind = .{ .reg = .eax } },
39713 .unused,39531 .unused,
...@@ -39750,7 +39568,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39750,7 +39568,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39750 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },39568 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
39751 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },39569 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
39752 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },39570 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },
39753 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodf" } } },39571 .{ .type = .usize, .kind = .{ .extern_func = "fmodf" } },
39754 .{ .type = .f32, .kind = .mem },39572 .{ .type = .f32, .kind = .mem },
39755 .{ .type = .f32, .kind = .{ .reg = .eax } },39573 .{ .type = .f32, .kind = .{ .reg = .eax } },
39756 .unused,39574 .unused,
...@@ -39790,7 +39608,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39790,7 +39608,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39790 .call_frame = .{ .alignment = .@"16" },39608 .call_frame = .{ .alignment = .@"16" },
39791 .extra_temps = .{39609 .extra_temps = .{
39792 .{ .type = .f64, .kind = .{ .rc = .general_purpose } },39610 .{ .type = .f64, .kind = .{ .rc = .general_purpose } },
39793 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmod" } } },39611 .{ .type = .usize, .kind = .{ .extern_func = "fmod" } },
39794 .{ .type = .f64, .kind = .{ .reg = .rcx } },39612 .{ .type = .f64, .kind = .{ .reg = .rcx } },
39795 .{ .type = .f64, .kind = .{ .reg = .rdx } },39613 .{ .type = .f64, .kind = .{ .reg = .rdx } },
39796 .{ .type = .f64, .kind = .{ .reg = .rax } },39614 .{ .type = .f64, .kind = .{ .reg = .rax } },
...@@ -39829,7 +39647,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39829,7 +39647,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39829 .call_frame = .{ .alignment = .@"16" },39647 .call_frame = .{ .alignment = .@"16" },
39830 .extra_temps = .{39648 .extra_temps = .{
39831 .{ .type = .f64, .kind = .{ .rc = .general_purpose } },39649 .{ .type = .f64, .kind = .{ .rc = .general_purpose } },
39832 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmod" } } },39650 .{ .type = .usize, .kind = .{ .extern_func = "fmod" } },
39833 .{ .type = .f64, .kind = .{ .reg = .rcx } },39651 .{ .type = .f64, .kind = .{ .reg = .rcx } },
39834 .{ .type = .f64, .kind = .{ .reg = .rdx } },39652 .{ .type = .f64, .kind = .{ .reg = .rdx } },
39835 .{ .type = .f64, .kind = .{ .reg = .rax } },39653 .{ .type = .f64, .kind = .{ .reg = .rax } },
...@@ -39868,7 +39686,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39868,7 +39686,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39868 .call_frame = .{ .alignment = .@"16" },39686 .call_frame = .{ .alignment = .@"16" },
39869 .extra_temps = .{39687 .extra_temps = .{
39870 .{ .type = .f64, .kind = .mem },39688 .{ .type = .f64, .kind = .mem },
39871 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmod" } } },39689 .{ .type = .usize, .kind = .{ .extern_func = "fmod" } },
39872 .{ .type = .f64, .kind = .mem },39690 .{ .type = .f64, .kind = .mem },
39873 .{ .type = .f64, .kind = .{ .reg = .rdx } },39691 .{ .type = .f64, .kind = .{ .reg = .rdx } },
39874 .{ .type = .f64, .kind = .{ .reg = .rax } },39692 .{ .type = .f64, .kind = .{ .reg = .rax } },
...@@ -39913,7 +39731,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39913,7 +39731,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39913 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },39731 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
39914 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },39732 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
39915 .{ .type = .f64, .kind = .{ .rc = .general_purpose } },39733 .{ .type = .f64, .kind = .{ .rc = .general_purpose } },
39916 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmod" } } },39734 .{ .type = .usize, .kind = .{ .extern_func = "fmod" } },
39917 .{ .type = .f64, .kind = .{ .reg = .rcx } },39735 .{ .type = .f64, .kind = .{ .reg = .rcx } },
39918 .{ .type = .f64, .kind = .{ .reg = .rdx } },39736 .{ .type = .f64, .kind = .{ .reg = .rdx } },
39919 .{ .type = .f64, .kind = .{ .reg = .rax } },39737 .{ .type = .f64, .kind = .{ .reg = .rax } },
...@@ -39958,7 +39776,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39958,7 +39776,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39958 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },39776 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
39959 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },39777 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
39960 .{ .type = .f64, .kind = .{ .rc = .general_purpose } },39778 .{ .type = .f64, .kind = .{ .rc = .general_purpose } },
39961 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmod" } } },39779 .{ .type = .usize, .kind = .{ .extern_func = "fmod" } },
39962 .{ .type = .f64, .kind = .{ .reg = .rcx } },39780 .{ .type = .f64, .kind = .{ .reg = .rcx } },
39963 .{ .type = .f64, .kind = .{ .reg = .rdx } },39781 .{ .type = .f64, .kind = .{ .reg = .rdx } },
39964 .{ .type = .f64, .kind = .{ .reg = .rax } },39782 .{ .type = .f64, .kind = .{ .reg = .rax } },
...@@ -40002,7 +39820,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40002,7 +39820,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40002 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },39820 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
40003 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },39821 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
40004 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },39822 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
40005 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmod" } } },39823 .{ .type = .usize, .kind = .{ .extern_func = "fmod" } },
40006 .{ .type = .f64, .kind = .{ .reg = .rdx } },39824 .{ .type = .f64, .kind = .{ .reg = .rdx } },
40007 .{ .type = .f64, .kind = .mem },39825 .{ .type = .f64, .kind = .mem },
40008 .{ .type = .f64, .kind = .{ .reg = .rax } },39826 .{ .type = .f64, .kind = .{ .reg = .rax } },
...@@ -40050,7 +39868,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40050,7 +39868,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40050 .extra_temps = .{39868 .extra_temps = .{
40051 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },39869 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
40052 .{ .type = .f80, .kind = .{ .frame = .call_frame } },39870 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
40053 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },39871 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
40054 .{ .type = .f80, .kind = .{ .reg = .st7 } },39872 .{ .type = .f80, .kind = .{ .reg = .st7 } },
40055 .{ .type = .f80, .kind = .{ .reg = .rax } },39873 .{ .type = .f80, .kind = .{ .reg = .rax } },
40056 .unused,39874 .unused,
...@@ -40093,7 +39911,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40093,7 +39911,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40093 .extra_temps = .{39911 .extra_temps = .{
40094 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },39912 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
40095 .{ .type = .f80, .kind = .{ .frame = .call_frame } },39913 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
40096 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },39914 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
40097 .{ .type = .f80, .kind = .{ .reg = .st7 } },39915 .{ .type = .f80, .kind = .{ .reg = .st7 } },
40098 .{ .type = .f80, .kind = .{ .reg = .rax } },39916 .{ .type = .f80, .kind = .{ .reg = .rax } },
40099 .unused,39917 .unused,
...@@ -40136,7 +39954,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40136,7 +39954,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40136 .extra_temps = .{39954 .extra_temps = .{
40137 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },39955 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
40138 .{ .type = .f80, .kind = .{ .frame = .call_frame } },39956 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
40139 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },39957 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
40140 .{ .type = .f80, .kind = .{ .reg = .st7 } },39958 .{ .type = .f80, .kind = .{ .reg = .st7 } },
40141 .{ .type = .f80, .kind = .{ .reg = .rax } },39959 .{ .type = .f80, .kind = .{ .reg = .rax } },
40142 .unused,39960 .unused,
...@@ -40179,7 +39997,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40179,7 +39997,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40179 .extra_temps = .{39997 .extra_temps = .{
40180 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },39998 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
40181 .{ .type = .f80, .kind = .{ .frame = .call_frame } },39999 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
40182 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },40000 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
40183 .{ .type = .f80, .kind = .{ .reg = .st7 } },40001 .{ .type = .f80, .kind = .{ .reg = .st7 } },
40184 .{ .type = .f80, .kind = .{ .reg = .rax } },40002 .{ .type = .f80, .kind = .{ .reg = .rax } },
40185 .unused,40003 .unused,
...@@ -40222,7 +40040,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40222,7 +40040,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40222 .extra_temps = .{40040 .extra_temps = .{
40223 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },40041 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
40224 .{ .type = .f80, .kind = .{ .frame = .call_frame } },40042 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
40225 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },40043 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
40226 .{ .type = .f80, .kind = .{ .reg = .st7 } },40044 .{ .type = .f80, .kind = .{ .reg = .st7 } },
40227 .{ .type = .f80, .kind = .{ .reg = .rax } },40045 .{ .type = .f80, .kind = .{ .reg = .rax } },
40228 .unused,40046 .unused,
...@@ -40265,7 +40083,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40265,7 +40083,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40265 .extra_temps = .{40083 .extra_temps = .{
40266 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },40084 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
40267 .{ .type = .f80, .kind = .{ .frame = .call_frame } },40085 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
40268 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },40086 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
40269 .{ .type = .f80, .kind = .{ .reg = .st7 } },40087 .{ .type = .f80, .kind = .{ .reg = .st7 } },
40270 .{ .type = .f80, .kind = .{ .reg = .rax } },40088 .{ .type = .f80, .kind = .{ .reg = .rax } },
40271 .unused,40089 .unused,
...@@ -40309,7 +40127,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40309,7 +40127,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40309 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },40127 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
40310 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },40128 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
40311 .{ .type = .f80, .kind = .{ .frame = .call_frame } },40129 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
40312 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },40130 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
40313 .{ .type = .f80, .kind = .{ .reg = .st7 } },40131 .{ .type = .f80, .kind = .{ .reg = .st7 } },
40314 .{ .type = .f80, .kind = .{ .reg = .rax } },40132 .{ .type = .f80, .kind = .{ .reg = .rax } },
40315 .unused,40133 .unused,
...@@ -40357,7 +40175,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40357,7 +40175,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40357 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },40175 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
40358 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },40176 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
40359 .{ .type = .f80, .kind = .{ .frame = .call_frame } },40177 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
40360 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },40178 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
40361 .{ .type = .f80, .kind = .{ .reg = .st7 } },40179 .{ .type = .f80, .kind = .{ .reg = .st7 } },
40362 .{ .type = .f80, .kind = .{ .reg = .rax } },40180 .{ .type = .f80, .kind = .{ .reg = .rax } },
40363 .unused,40181 .unused,
...@@ -40405,7 +40223,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40405,7 +40223,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40405 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },40223 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
40406 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },40224 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
40407 .{ .type = .f80, .kind = .{ .frame = .call_frame } },40225 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
40408 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },40226 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
40409 .{ .type = .f80, .kind = .{ .reg = .st7 } },40227 .{ .type = .f80, .kind = .{ .reg = .st7 } },
40410 .{ .type = .f80, .kind = .{ .reg = .rax } },40228 .{ .type = .f80, .kind = .{ .reg = .rax } },
40411 .unused,40229 .unused,
...@@ -40453,7 +40271,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40453,7 +40271,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40453 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },40271 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
40454 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },40272 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
40455 .{ .type = .f80, .kind = .{ .frame = .call_frame } },40273 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
40456 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },40274 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
40457 .{ .type = .f80, .kind = .{ .reg = .st7 } },40275 .{ .type = .f80, .kind = .{ .reg = .st7 } },
40458 .{ .type = .f80, .kind = .{ .reg = .rax } },40276 .{ .type = .f80, .kind = .{ .reg = .rax } },
40459 .unused,40277 .unused,
...@@ -40501,7 +40319,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40501,7 +40319,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40501 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },40319 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
40502 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },40320 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
40503 .{ .type = .f80, .kind = .{ .frame = .call_frame } },40321 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
40504 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },40322 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
40505 .{ .type = .f80, .kind = .{ .reg = .st7 } },40323 .{ .type = .f80, .kind = .{ .reg = .st7 } },
40506 .{ .type = .f80, .kind = .{ .reg = .rax } },40324 .{ .type = .f80, .kind = .{ .reg = .rax } },
40507 .unused,40325 .unused,
...@@ -40549,7 +40367,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40549,7 +40367,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40549 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },40367 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
40550 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },40368 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
40551 .{ .type = .f80, .kind = .{ .frame = .call_frame } },40369 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
40552 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmodx" } } },40370 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
40553 .{ .type = .f80, .kind = .{ .reg = .st7 } },40371 .{ .type = .f80, .kind = .{ .reg = .st7 } },
40554 .{ .type = .f80, .kind = .{ .reg = .rax } },40372 .{ .type = .f80, .kind = .{ .reg = .rax } },
40555 .unused,40373 .unused,
...@@ -40595,11 +40413,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40595,11 +40413,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40595 .call_frame = .{ .alignment = .@"16" },40413 .call_frame = .{ .alignment = .@"16" },
40596 .extra_temps = .{40414 .extra_temps = .{
40597 .{ .type = .f128, .kind = .mem },40415 .{ .type = .f128, .kind = .mem },
40598 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodq" } } },40416 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
40599 .{ .type = .f128, .kind = .{ .reg = .rcx } },40417 .{ .type = .f128, .kind = .{ .reg = .rcx } },
40600 .{ .type = .f128, .kind = .{ .reg = .rdx } },40418 .{ .type = .f128, .kind = .{ .reg = .rdx } },
40601 .{ .type = .f128, .kind = .{ .reg = .rax } },40419 .{ .type = .f128, .kind = .{ .reg = .rax } },
40602 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },40420 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
40603 .unused,40421 .unused,
40604 .unused,40422 .unused,
40605 .unused,40423 .unused,
...@@ -40636,11 +40454,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40636,11 +40454,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40636 .call_frame = .{ .alignment = .@"16" },40454 .call_frame = .{ .alignment = .@"16" },
40637 .extra_temps = .{40455 .extra_temps = .{
40638 .{ .type = .f128, .kind = .mem },40456 .{ .type = .f128, .kind = .mem },
40639 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodq" } } },40457 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
40640 .{ .type = .f128, .kind = .{ .reg = .rcx } },40458 .{ .type = .f128, .kind = .{ .reg = .rcx } },
40641 .{ .type = .f128, .kind = .{ .reg = .rdx } },40459 .{ .type = .f128, .kind = .{ .reg = .rdx } },
40642 .{ .type = .f128, .kind = .{ .reg = .rax } },40460 .{ .type = .f128, .kind = .{ .reg = .rax } },
40643 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },40461 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
40644 .unused,40462 .unused,
40645 .unused,40463 .unused,
40646 .unused,40464 .unused,
...@@ -40677,11 +40495,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40677,11 +40495,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40677 .call_frame = .{ .alignment = .@"16" },40495 .call_frame = .{ .alignment = .@"16" },
40678 .extra_temps = .{40496 .extra_temps = .{
40679 .{ .type = .f128, .kind = .mem },40497 .{ .type = .f128, .kind = .mem },
40680 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodq" } } },40498 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
40681 .{ .type = .f128, .kind = .{ .reg = .rcx } },40499 .{ .type = .f128, .kind = .{ .reg = .rcx } },
40682 .{ .type = .f128, .kind = .{ .reg = .rdx } },40500 .{ .type = .f128, .kind = .{ .reg = .rdx } },
40683 .{ .type = .f128, .kind = .{ .reg = .rax } },40501 .{ .type = .f128, .kind = .{ .reg = .rax } },
40684 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },40502 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
40685 .unused,40503 .unused,
40686 .unused,40504 .unused,
40687 .unused,40505 .unused,
...@@ -40719,11 +40537,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40719,11 +40537,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40719 .call_frame = .{ .alignment = .@"16" },40537 .call_frame = .{ .alignment = .@"16" },
40720 .extra_temps = .{40538 .extra_temps = .{
40721 .{ .type = .f128, .kind = .mem },40539 .{ .type = .f128, .kind = .mem },
40722 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodq" } } },40540 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
40723 .{ .type = .f128, .kind = .{ .reg = .rdx } },40541 .{ .type = .f128, .kind = .{ .reg = .rdx } },
40724 .{ .type = .f128, .kind = .mem },40542 .{ .type = .f128, .kind = .mem },
40725 .{ .type = .f128, .kind = .{ .reg = .rax } },40543 .{ .type = .f128, .kind = .{ .reg = .rax } },
40726 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },40544 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
40727 .unused,40545 .unused,
40728 .unused,40546 .unused,
40729 .unused,40547 .unused,
...@@ -40761,11 +40579,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40761,11 +40579,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40761 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },40579 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
40762 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },40580 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
40763 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },40581 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
40764 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodq" } } },40582 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
40765 .{ .type = .f128, .kind = .{ .reg = .rcx } },40583 .{ .type = .f128, .kind = .{ .reg = .rcx } },
40766 .{ .type = .f128, .kind = .{ .reg = .rdx } },40584 .{ .type = .f128, .kind = .{ .reg = .rdx } },
40767 .{ .type = .f128, .kind = .{ .reg = .rax } },40585 .{ .type = .f128, .kind = .{ .reg = .rax } },
40768 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },40586 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
40769 .unused,40587 .unused,
40770 .unused,40588 .unused,
40771 .unused,40589 .unused,
...@@ -40807,11 +40625,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40807,11 +40625,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40807 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },40625 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
40808 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },40626 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
40809 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },40627 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
40810 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodq" } } },40628 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
40811 .{ .type = .f128, .kind = .{ .reg = .rcx } },40629 .{ .type = .f128, .kind = .{ .reg = .rcx } },
40812 .{ .type = .f128, .kind = .{ .reg = .rdx } },40630 .{ .type = .f128, .kind = .{ .reg = .rdx } },
40813 .{ .type = .f128, .kind = .{ .reg = .rax } },40631 .{ .type = .f128, .kind = .{ .reg = .rax } },
40814 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },40632 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
40815 .unused,40633 .unused,
40816 .unused,40634 .unused,
40817 .unused,40635 .unused,
...@@ -40853,11 +40671,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40853,11 +40671,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40853 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },40671 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
40854 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },40672 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
40855 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },40673 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
40856 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodq" } } },40674 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
40857 .{ .type = .f128, .kind = .{ .reg = .rcx } },40675 .{ .type = .f128, .kind = .{ .reg = .rcx } },
40858 .{ .type = .f128, .kind = .{ .reg = .rdx } },40676 .{ .type = .f128, .kind = .{ .reg = .rdx } },
40859 .{ .type = .f128, .kind = .{ .reg = .rax } },40677 .{ .type = .f128, .kind = .{ .reg = .rax } },
40860 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },40678 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
40861 .unused,40679 .unused,
40862 .unused,40680 .unused,
40863 .unused,40681 .unused,
...@@ -40900,11 +40718,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -40900,11 +40718,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40900 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },40718 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
40901 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },40719 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
40902 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },40720 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
40903 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmodq" } } },40721 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
40904 .{ .type = .f128, .kind = .{ .reg = .rdx } },40722 .{ .type = .f128, .kind = .{ .reg = .rdx } },
40905 .{ .type = .f128, .kind = .mem },40723 .{ .type = .f128, .kind = .mem },
40906 .{ .type = .f128, .kind = .{ .reg = .rax } },40724 .{ .type = .f128, .kind = .{ .reg = .rax } },
40907 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },40725 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
40908 .unused,40726 .unused,
40909 .unused,40727 .unused,
40910 .unused,40728 .unused,
...@@ -43994,7 +43812,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -43994,7 +43812,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43994 },43812 },
43995 .call_frame = .{ .alignment = .@"16" },43813 .call_frame = .{ .alignment = .@"16" },
43996 .extra_temps = .{43814 .extra_temps = .{
43997 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmaxh" } } },43815 .{ .type = .usize, .kind = .{ .extern_func = "__fmaxh" } },
43998 .unused,43816 .unused,
43999 .unused,43817 .unused,
44000 .unused,43818 .unused,
...@@ -44132,7 +43950,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -44132,7 +43950,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
44132 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },43950 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
44133 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },43951 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
44134 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },43952 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
44135 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmaxh" } } },43953 .{ .type = .usize, .kind = .{ .extern_func = "__fmaxh" } },
44136 .unused,43954 .unused,
44137 .unused,43955 .unused,
44138 .unused,43956 .unused,
...@@ -44168,7 +43986,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -44168,7 +43986,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
44168 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },43986 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
44169 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },43987 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
44170 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },43988 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
44171 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmaxh" } } },43989 .{ .type = .usize, .kind = .{ .extern_func = "__fmaxh" } },
44172 .unused,43990 .unused,
44173 .unused,43991 .unused,
44174 .unused,43992 .unused,
...@@ -44205,7 +44023,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -44205,7 +44023,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
44205 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },44023 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
44206 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },44024 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
44207 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },44025 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
44208 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmaxh" } } },44026 .{ .type = .usize, .kind = .{ .extern_func = "__fmaxh" } },
44209 .{ .type = .f16, .kind = .{ .reg = .ax } },44027 .{ .type = .f16, .kind = .{ .reg = .ax } },
44210 .unused,44028 .unused,
44211 .unused,44029 .unused,
...@@ -44245,7 +44063,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -44245,7 +44063,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
44245 .{ .type = .f32, .kind = .mem },44063 .{ .type = .f32, .kind = .mem },
44246 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },44064 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
44247 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },44065 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
44248 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmaxh" } } },44066 .{ .type = .usize, .kind = .{ .extern_func = "__fmaxh" } },
44249 .unused,44067 .unused,
44250 .unused,44068 .unused,
44251 .unused,44069 .unused,
...@@ -44660,7 +44478,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -44660,7 +44478,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
44660 },44478 },
44661 .call_frame = .{ .alignment = .@"16" },44479 .call_frame = .{ .alignment = .@"16" },
44662 .extra_temps = .{44480 .extra_temps = .{
44663 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmax" } } },44481 .{ .type = .usize, .kind = .{ .extern_func = "fmax" } },
44664 .unused,44482 .unused,
44665 .unused,44483 .unused,
44666 .unused,44484 .unused,
...@@ -44915,7 +44733,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -44915,7 +44733,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
44915 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },44733 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
44916 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },44734 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
44917 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },44735 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
44918 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmax" } } },44736 .{ .type = .usize, .kind = .{ .extern_func = "fmax" } },
44919 .unused,44737 .unused,
44920 .unused,44738 .unused,
44921 .unused,44739 .unused,
...@@ -45204,7 +45022,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -45204,7 +45022,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
45204 },45022 },
45205 .call_frame = .{ .alignment = .@"16" },45023 .call_frame = .{ .alignment = .@"16" },
45206 .extra_temps = .{45024 .extra_temps = .{
45207 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaxq" } } },45025 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
45208 .unused,45026 .unused,
45209 .unused,45027 .unused,
45210 .unused,45028 .unused,
...@@ -45236,7 +45054,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -45236,7 +45054,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
45236 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },45054 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
45237 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },45055 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
45238 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },45056 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
45239 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaxq" } } },45057 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
45240 .unused,45058 .unused,
45241 .unused,45059 .unused,
45242 .unused,45060 .unused,
...@@ -45271,7 +45089,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -45271,7 +45089,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
45271 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },45089 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
45272 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },45090 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
45273 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },45091 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
45274 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaxq" } } },45092 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
45275 .unused,45093 .unused,
45276 .unused,45094 .unused,
45277 .unused,45095 .unused,
...@@ -45306,7 +45124,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -45306,7 +45124,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
45306 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },45124 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
45307 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },45125 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
45308 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },45126 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
45309 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaxq" } } },45127 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
45310 .unused,45128 .unused,
45311 .unused,45129 .unused,
45312 .unused,45130 .unused,
...@@ -48153,7 +47971,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -48153,7 +47971,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
48153 },47971 },
48154 .call_frame = .{ .alignment = .@"16" },47972 .call_frame = .{ .alignment = .@"16" },
48155 .extra_temps = .{47973 .extra_temps = .{
48156 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fminh" } } },47974 .{ .type = .usize, .kind = .{ .extern_func = "__fminh" } },
48157 .unused,47975 .unused,
48158 .unused,47976 .unused,
48159 .unused,47977 .unused,
...@@ -48291,7 +48109,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -48291,7 +48109,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
48291 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },48109 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
48292 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },48110 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
48293 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },48111 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
48294 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fminh" } } },48112 .{ .type = .usize, .kind = .{ .extern_func = "__fminh" } },
48295 .unused,48113 .unused,
48296 .unused,48114 .unused,
48297 .unused,48115 .unused,
...@@ -48327,7 +48145,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -48327,7 +48145,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
48327 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },48145 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
48328 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },48146 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
48329 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },48147 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
48330 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fminh" } } },48148 .{ .type = .usize, .kind = .{ .extern_func = "__fminh" } },
48331 .unused,48149 .unused,
48332 .unused,48150 .unused,
48333 .unused,48151 .unused,
...@@ -48364,7 +48182,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -48364,7 +48182,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
48364 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },48182 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
48365 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },48183 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
48366 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },48184 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
48367 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fminh" } } },48185 .{ .type = .usize, .kind = .{ .extern_func = "__fminh" } },
48368 .{ .type = .f16, .kind = .{ .reg = .ax } },48186 .{ .type = .f16, .kind = .{ .reg = .ax } },
48369 .unused,48187 .unused,
48370 .unused,48188 .unused,
...@@ -48404,7 +48222,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -48404,7 +48222,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
48404 .{ .type = .f32, .kind = .mem },48222 .{ .type = .f32, .kind = .mem },
48405 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },48223 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
48406 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },48224 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
48407 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fminh" } } },48225 .{ .type = .usize, .kind = .{ .extern_func = "__fminh" } },
48408 .unused,48226 .unused,
48409 .unused,48227 .unused,
48410 .unused,48228 .unused,
...@@ -48819,7 +48637,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -48819,7 +48637,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
48819 },48637 },
48820 .call_frame = .{ .alignment = .@"16" },48638 .call_frame = .{ .alignment = .@"16" },
48821 .extra_temps = .{48639 .extra_temps = .{
48822 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmin" } } },48640 .{ .type = .usize, .kind = .{ .extern_func = "fmin" } },
48823 .unused,48641 .unused,
48824 .unused,48642 .unused,
48825 .unused,48643 .unused,
...@@ -49074,7 +48892,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -49074,7 +48892,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
49074 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },48892 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
49075 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },48893 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
49076 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },48894 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
49077 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmin" } } },48895 .{ .type = .usize, .kind = .{ .extern_func = "fmin" } },
49078 .unused,48896 .unused,
49079 .unused,48897 .unused,
49080 .unused,48898 .unused,
...@@ -49351,7 +49169,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -49351,7 +49169,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
49351 },49169 },
49352 .call_frame = .{ .alignment = .@"16" },49170 .call_frame = .{ .alignment = .@"16" },
49353 .extra_temps = .{49171 .extra_temps = .{
49354 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fminq" } } },49172 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
49355 .unused,49173 .unused,
49356 .unused,49174 .unused,
49357 .unused,49175 .unused,
...@@ -49383,7 +49201,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -49383,7 +49201,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
49383 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },49201 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
49384 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },49202 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
49385 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },49203 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
49386 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fminq" } } },49204 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
49387 .unused,49205 .unused,
49388 .unused,49206 .unused,
49389 .unused,49207 .unused,
...@@ -49418,7 +49236,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -49418,7 +49236,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
49418 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },49236 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
49419 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },49237 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
49420 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },49238 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
49421 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fminq" } } },49239 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
49422 .unused,49240 .unused,
49423 .unused,49241 .unused,
49424 .unused,49242 .unused,
...@@ -49453,7 +49271,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -49453,7 +49271,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
49453 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },49271 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
49454 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },49272 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
49455 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },49273 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
49456 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fminq" } } },49274 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
49457 .unused,49275 .unused,
49458 .unused,49276 .unused,
49459 .unused,49277 .unused,
...@@ -64179,9 +63997,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -64179,9 +63997,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
64179 .block => {63997 .block => {
64180 const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;63998 const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;
64181 const block = cg.air.extraData(Air.Block, ty_pl.payload);63999 const block = cg.air.extraData(Air.Block, ty_pl.payload);
64182 if (cg.debug_output != .none) try cg.asmPseudo(.pseudo_dbg_enter_block_none);64000 if (!cg.mod.strip) try cg.asmPseudo(.pseudo_dbg_enter_block_none);
64183 try cg.lowerBlock(inst, @ptrCast(cg.air.extra.items[block.end..][0..block.data.body_len]));64001 try cg.lowerBlock(inst, @ptrCast(cg.air.extra.items[block.end..][0..block.data.body_len]));
64184 if (cg.debug_output != .none) try cg.asmPseudo(.pseudo_dbg_leave_block_none);64002 if (!cg.mod.strip) try cg.asmPseudo(.pseudo_dbg_leave_block_none);
64185 },64003 },
64186 .loop => if (use_old) try cg.airLoop(inst) else {64004 .loop => if (use_old) try cg.airLoop(inst) else {
64187 const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;64005 const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;
...@@ -72393,7 +72211,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -72393,7 +72211,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
72393 },72211 },
72394 .call_frame = .{ .alignment = .@"16" },72212 .call_frame = .{ .alignment = .@"16" },
72395 .extra_temps = .{72213 .extra_temps = .{
72396 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__sqrth" } } },72214 .{ .type = .usize, .kind = .{ .extern_func = "__sqrth" } },
72397 .unused,72215 .unused,
72398 .unused,72216 .unused,
72399 .unused,72217 .unused,
...@@ -72475,7 +72293,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -72475,7 +72293,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
72475 .extra_temps = .{72293 .extra_temps = .{
72476 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },72294 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
72477 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },72295 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
72478 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__sqrth" } } },72296 .{ .type = .usize, .kind = .{ .extern_func = "__sqrth" } },
72479 .unused,72297 .unused,
72480 .unused,72298 .unused,
72481 .unused,72299 .unused,
...@@ -72506,7 +72324,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -72506,7 +72324,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
72506 .extra_temps = .{72324 .extra_temps = .{
72507 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },72325 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
72508 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },72326 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
72509 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__sqrth" } } },72327 .{ .type = .usize, .kind = .{ .extern_func = "__sqrth" } },
72510 .unused,72328 .unused,
72511 .unused,72329 .unused,
72512 .unused,72330 .unused,
...@@ -72537,7 +72355,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -72537,7 +72355,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
72537 .extra_temps = .{72355 .extra_temps = .{
72538 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },72356 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
72539 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },72357 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
72540 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__sqrth" } } },72358 .{ .type = .usize, .kind = .{ .extern_func = "__sqrth" } },
72541 .{ .type = .f16, .kind = .{ .reg = .ax } },72359 .{ .type = .f16, .kind = .{ .reg = .ax } },
72542 .unused,72360 .unused,
72543 .unused,72361 .unused,
...@@ -72571,7 +72389,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -72571,7 +72389,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
72571 .{ .type = .f16, .kind = .{ .reg = .ax } },72389 .{ .type = .f16, .kind = .{ .reg = .ax } },
72572 .{ .type = .f32, .kind = .mem },72390 .{ .type = .f32, .kind = .mem },
72573 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },72391 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
72574 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__sqrth" } } },72392 .{ .type = .usize, .kind = .{ .extern_func = "__sqrth" } },
72575 .unused,72393 .unused,
72576 .unused,72394 .unused,
72577 .unused,72395 .unused,
...@@ -72643,7 +72461,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -72643,7 +72461,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
72643 },72461 },
72644 .call_frame = .{ .alignment = .@"16" },72462 .call_frame = .{ .alignment = .@"16" },
72645 .extra_temps = .{72463 .extra_temps = .{
72646 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "sqrtf" } } },72464 .{ .type = .usize, .kind = .{ .extern_func = "sqrtf" } },
72647 .unused,72465 .unused,
72648 .unused,72466 .unused,
72649 .unused,72467 .unused,
...@@ -72759,7 +72577,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -72759,7 +72577,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
72759 .extra_temps = .{72577 .extra_temps = .{
72760 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },72578 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
72761 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },72579 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
72762 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "sqrtf" } } },72580 .{ .type = .usize, .kind = .{ .extern_func = "sqrtf" } },
72763 .unused,72581 .unused,
72764 .unused,72582 .unused,
72765 .unused,72583 .unused,
...@@ -72789,7 +72607,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -72789,7 +72607,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
72789 .extra_temps = .{72607 .extra_temps = .{
72790 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },72608 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
72791 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },72609 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
72792 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "sqrtf" } } },72610 .{ .type = .usize, .kind = .{ .extern_func = "sqrtf" } },
72793 .unused,72611 .unused,
72794 .unused,72612 .unused,
72795 .unused,72613 .unused,
...@@ -72859,7 +72677,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -72859,7 +72677,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
72859 },72677 },
72860 .call_frame = .{ .alignment = .@"16" },72678 .call_frame = .{ .alignment = .@"16" },
72861 .extra_temps = .{72679 .extra_temps = .{
72862 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "sqrt" } } },72680 .{ .type = .usize, .kind = .{ .extern_func = "sqrt" } },
72863 .unused,72681 .unused,
72864 .unused,72682 .unused,
72865 .unused,72683 .unused,
...@@ -72975,7 +72793,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -72975,7 +72793,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
72975 .extra_temps = .{72793 .extra_temps = .{
72976 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },72794 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
72977 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },72795 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
72978 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "sqrt" } } },72796 .{ .type = .usize, .kind = .{ .extern_func = "sqrt" } },
72979 .unused,72797 .unused,
72980 .unused,72798 .unused,
72981 .unused,72799 .unused,
...@@ -73005,7 +72823,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73005,7 +72823,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73005 .extra_temps = .{72823 .extra_temps = .{
73006 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },72824 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73007 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },72825 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
73008 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "sqrt" } } },72826 .{ .type = .usize, .kind = .{ .extern_func = "sqrt" } },
73009 .unused,72827 .unused,
73010 .unused,72828 .unused,
73011 .unused,72829 .unused,
...@@ -73035,7 +72853,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73035,7 +72853,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73035 .extra_temps = .{72853 .extra_temps = .{
73036 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },72854 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73037 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },72855 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
73038 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "sqrt" } } },72856 .{ .type = .usize, .kind = .{ .extern_func = "sqrt" } },
73039 .unused,72857 .unused,
73040 .unused,72858 .unused,
73041 .unused,72859 .unused,
...@@ -73119,7 +72937,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73119,7 +72937,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73119 },72937 },
73120 .call_frame = .{ .alignment = .@"16" },72938 .call_frame = .{ .alignment = .@"16" },
73121 .extra_temps = .{72939 .extra_temps = .{
73122 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "sqrtq" } } },72940 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },
73123 .unused,72941 .unused,
73124 .unused,72942 .unused,
73125 .unused,72943 .unused,
...@@ -73146,7 +72964,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73146,7 +72964,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73146 .extra_temps = .{72964 .extra_temps = .{
73147 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },72965 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73148 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },72966 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
73149 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "sqrtq" } } },72967 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },
73150 .unused,72968 .unused,
73151 .unused,72969 .unused,
73152 .unused,72970 .unused,
...@@ -73176,7 +72994,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73176,7 +72994,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73176 .extra_temps = .{72994 .extra_temps = .{
73177 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },72995 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73178 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },72996 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
73179 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "sqrtq" } } },72997 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },
73180 .unused,72998 .unused,
73181 .unused,72999 .unused,
73182 .unused,73000 .unused,
...@@ -73206,7 +73024,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73206,7 +73024,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73206 .extra_temps = .{73024 .extra_temps = .{
73207 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73025 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73208 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },73026 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
73209 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "sqrtq" } } },73027 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },
73210 .unused,73028 .unused,
73211 .unused,73029 .unused,
73212 .unused,73030 .unused,
...@@ -73250,7 +73068,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73250,7 +73068,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73250 },73068 },
73251 .call_frame = .{ .alignment = .@"16" },73069 .call_frame = .{ .alignment = .@"16" },
73252 .extra_temps = .{73070 .extra_temps = .{
73253 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__" ++ @tagName(name) ++ "h" } } },73071 .{ .type = .usize, .kind = .{ .extern_func = "__" ++ @tagName(name) ++ "h" } },
73254 .unused,73072 .unused,
73255 .unused,73073 .unused,
73256 .unused,73074 .unused,
...@@ -73277,7 +73095,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73277,7 +73095,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73277 .extra_temps = .{73095 .extra_temps = .{
73278 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73096 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73279 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },73097 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
73280 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__" ++ @tagName(name) ++ "h" } } },73098 .{ .type = .usize, .kind = .{ .extern_func = "__" ++ @tagName(name) ++ "h" } },
73281 .unused,73099 .unused,
73282 .unused,73100 .unused,
73283 .unused,73101 .unused,
...@@ -73308,7 +73126,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73308,7 +73126,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73308 .extra_temps = .{73126 .extra_temps = .{
73309 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73127 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73310 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },73128 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
73311 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__" ++ @tagName(name) ++ "h" } } },73129 .{ .type = .usize, .kind = .{ .extern_func = "__" ++ @tagName(name) ++ "h" } },
73312 .unused,73130 .unused,
73313 .unused,73131 .unused,
73314 .unused,73132 .unused,
...@@ -73339,7 +73157,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73339,7 +73157,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73339 .extra_temps = .{73157 .extra_temps = .{
73340 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73158 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73341 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },73159 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
73342 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__" ++ @tagName(name) ++ "h" } } },73160 .{ .type = .usize, .kind = .{ .extern_func = "__" ++ @tagName(name) ++ "h" } },
73343 .{ .type = .f16, .kind = .{ .reg = .ax } },73161 .{ .type = .f16, .kind = .{ .reg = .ax } },
73344 .unused,73162 .unused,
73345 .unused,73163 .unused,
...@@ -73373,7 +73191,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73373,7 +73191,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73373 .{ .type = .f16, .kind = .{ .reg = .ax } },73191 .{ .type = .f16, .kind = .{ .reg = .ax } },
73374 .{ .type = .f32, .kind = .mem },73192 .{ .type = .f32, .kind = .mem },
73375 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },73193 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
73376 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__" ++ @tagName(name) ++ "h" } } },73194 .{ .type = .usize, .kind = .{ .extern_func = "__" ++ @tagName(name) ++ "h" } },
73377 .unused,73195 .unused,
73378 .unused,73196 .unused,
73379 .unused,73197 .unused,
...@@ -73403,7 +73221,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73403,7 +73221,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73403 },73221 },
73404 .call_frame = .{ .alignment = .@"16" },73222 .call_frame = .{ .alignment = .@"16" },
73405 .extra_temps = .{73223 .extra_temps = .{
73406 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = @tagName(name) ++ "f" } } },73224 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f" } },
73407 .unused,73225 .unused,
73408 .unused,73226 .unused,
73409 .unused,73227 .unused,
...@@ -73430,7 +73248,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73430,7 +73248,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73430 .extra_temps = .{73248 .extra_temps = .{
73431 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73249 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73432 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },73250 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
73433 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = @tagName(name) ++ "f" } } },73251 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f" } },
73434 .unused,73252 .unused,
73435 .unused,73253 .unused,
73436 .unused,73254 .unused,
...@@ -73460,7 +73278,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73460,7 +73278,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73460 .extra_temps = .{73278 .extra_temps = .{
73461 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73279 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73462 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },73280 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
73463 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = @tagName(name) ++ "f" } } },73281 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f" } },
73464 .unused,73282 .unused,
73465 .unused,73283 .unused,
73466 .unused,73284 .unused,
...@@ -73488,7 +73306,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73488,7 +73306,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73488 },73306 },
73489 .call_frame = .{ .alignment = .@"16" },73307 .call_frame = .{ .alignment = .@"16" },
73490 .extra_temps = .{73308 .extra_temps = .{
73491 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = @tagName(name) } } },73309 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) } },
73492 .unused,73310 .unused,
73493 .unused,73311 .unused,
73494 .unused,73312 .unused,
...@@ -73515,7 +73333,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73515,7 +73333,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73515 .extra_temps = .{73333 .extra_temps = .{
73516 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73334 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73517 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },73335 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
73518 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = @tagName(name) } } },73336 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) } },
73519 .unused,73337 .unused,
73520 .unused,73338 .unused,
73521 .unused,73339 .unused,
...@@ -73545,7 +73363,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73545,7 +73363,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73545 .extra_temps = .{73363 .extra_temps = .{
73546 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73364 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73547 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },73365 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
73548 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = @tagName(name) } } },73366 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) } },
73549 .unused,73367 .unused,
73550 .unused,73368 .unused,
73551 .unused,73369 .unused,
...@@ -73575,7 +73393,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73575,7 +73393,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73575 .extra_temps = .{73393 .extra_temps = .{
73576 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73394 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73577 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },73395 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
73578 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = @tagName(name) } } },73396 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) } },
73579 .unused,73397 .unused,
73580 .unused,73398 .unused,
73581 .unused,73399 .unused,
...@@ -73606,7 +73424,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73606,7 +73424,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73606 .extra_temps = .{73424 .extra_temps = .{
73607 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },73425 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
73608 .{ .type = .f80, .kind = .{ .frame = .call_frame } },73426 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
73609 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__" ++ @tagName(name) ++ "x" } } },73427 .{ .type = .usize, .kind = .{ .extern_func = "__" ++ @tagName(name) ++ "x" } },
73610 .unused,73428 .unused,
73611 .unused,73429 .unused,
73612 .unused,73430 .unused,
...@@ -73633,7 +73451,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73633,7 +73451,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73633 .extra_temps = .{73451 .extra_temps = .{
73634 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },73452 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
73635 .{ .type = .f80, .kind = .{ .frame = .call_frame } },73453 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
73636 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__" ++ @tagName(name) ++ "x" } } },73454 .{ .type = .usize, .kind = .{ .extern_func = "__" ++ @tagName(name) ++ "x" } },
73637 .unused,73455 .unused,
73638 .unused,73456 .unused,
73639 .unused,73457 .unused,
...@@ -73660,7 +73478,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73660,7 +73478,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73660 .extra_temps = .{73478 .extra_temps = .{
73661 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },73479 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
73662 .{ .type = .f80, .kind = .{ .frame = .call_frame } },73480 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
73663 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__" ++ @tagName(name) ++ "x" } } },73481 .{ .type = .usize, .kind = .{ .extern_func = "__" ++ @tagName(name) ++ "x" } },
73664 .unused,73482 .unused,
73665 .unused,73483 .unused,
73666 .unused,73484 .unused,
...@@ -73688,7 +73506,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73688,7 +73506,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73688 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73506 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73689 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },73507 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
73690 .{ .type = .f80, .kind = .{ .frame = .call_frame } },73508 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
73691 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__" ++ @tagName(name) ++ "x" } } },73509 .{ .type = .usize, .kind = .{ .extern_func = "__" ++ @tagName(name) ++ "x" } },
73692 .unused,73510 .unused,
73693 .unused,73511 .unused,
73694 .unused,73512 .unused,
...@@ -73720,7 +73538,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73720,7 +73538,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73720 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73538 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73721 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },73539 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
73722 .{ .type = .f80, .kind = .{ .frame = .call_frame } },73540 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
73723 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__" ++ @tagName(name) ++ "x" } } },73541 .{ .type = .usize, .kind = .{ .extern_func = "__" ++ @tagName(name) ++ "x" } },
73724 .unused,73542 .unused,
73725 .unused,73543 .unused,
73726 .unused,73544 .unused,
...@@ -73752,7 +73570,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73752,7 +73570,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73752 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73570 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73753 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },73571 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
73754 .{ .type = .f80, .kind = .{ .frame = .call_frame } },73572 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
73755 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__" ++ @tagName(name) ++ "x" } } },73573 .{ .type = .usize, .kind = .{ .extern_func = "__" ++ @tagName(name) ++ "x" } },
73756 .unused,73574 .unused,
73757 .unused,73575 .unused,
73758 .unused,73576 .unused,
...@@ -73781,7 +73599,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73781,7 +73599,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73781 },73599 },
73782 .call_frame = .{ .alignment = .@"16" },73600 .call_frame = .{ .alignment = .@"16" },
73783 .extra_temps = .{73601 .extra_temps = .{
73784 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = @tagName(name) ++ "q" } } },73602 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },
73785 .unused,73603 .unused,
73786 .unused,73604 .unused,
73787 .unused,73605 .unused,
...@@ -73808,7 +73626,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73808,7 +73626,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73808 .extra_temps = .{73626 .extra_temps = .{
73809 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73627 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73810 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },73628 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
73811 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = @tagName(name) ++ "q" } } },73629 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },
73812 .unused,73630 .unused,
73813 .unused,73631 .unused,
73814 .unused,73632 .unused,
...@@ -73838,7 +73656,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73838,7 +73656,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73838 .extra_temps = .{73656 .extra_temps = .{
73839 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73657 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73840 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },73658 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
73841 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = @tagName(name) ++ "q" } } },73659 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },
73842 .unused,73660 .unused,
73843 .unused,73661 .unused,
73844 .unused,73662 .unused,
...@@ -73868,7 +73686,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -73868,7 +73686,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73868 .extra_temps = .{73686 .extra_temps = .{
73869 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },73687 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
73870 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },73688 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
73871 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = @tagName(name) ++ "q" } } },73689 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },
73872 .unused,73690 .unused,
73873 .unused,73691 .unused,
73874 .unused,73692 .unused,
...@@ -75486,12 +75304,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -75486,12 +75304,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
75486 },75304 },
75487 .call_frame = .{ .alignment = .@"16" },75305 .call_frame = .{ .alignment = .@"16" },
75488 .extra_temps = .{75306 .extra_temps = .{
75489 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {75307 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
75490 else => unreachable,75308 else => unreachable,
75491 .down => "__floorh",75309 .down => "__floorh",
75492 .up => "__ceilh",75310 .up => "__ceilh",
75493 .zero => "__trunch",75311 .zero => "__trunch",
75494 } } } },75312 } } },
75495 .unused,75313 .unused,
75496 .unused,75314 .unused,
75497 .unused,75315 .unused,
...@@ -75573,12 +75391,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -75573,12 +75391,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
75573 .extra_temps = .{75391 .extra_temps = .{
75574 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },75392 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
75575 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },75393 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
75576 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {75394 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
75577 else => unreachable,75395 else => unreachable,
75578 .down => "__floorh",75396 .down => "__floorh",
75579 .up => "__ceilh",75397 .up => "__ceilh",
75580 .zero => "__trunch",75398 .zero => "__trunch",
75581 } } } },75399 } } },
75582 .unused,75400 .unused,
75583 .unused,75401 .unused,
75584 .unused,75402 .unused,
...@@ -75609,12 +75427,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -75609,12 +75427,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
75609 .extra_temps = .{75427 .extra_temps = .{
75610 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },75428 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
75611 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },75429 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
75612 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {75430 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
75613 else => unreachable,75431 else => unreachable,
75614 .down => "__floorh",75432 .down => "__floorh",
75615 .up => "__ceilh",75433 .up => "__ceilh",
75616 .zero => "__trunch",75434 .zero => "__trunch",
75617 } } } },75435 } } },
75618 .unused,75436 .unused,
75619 .unused,75437 .unused,
75620 .unused,75438 .unused,
...@@ -75645,12 +75463,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -75645,12 +75463,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
75645 .extra_temps = .{75463 .extra_temps = .{
75646 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },75464 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
75647 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },75465 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
75648 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {75466 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
75649 else => unreachable,75467 else => unreachable,
75650 .down => "__floorh",75468 .down => "__floorh",
75651 .up => "__ceilh",75469 .up => "__ceilh",
75652 .zero => "__trunch",75470 .zero => "__trunch",
75653 } } } },75471 } } },
75654 .{ .type = .f16, .kind = .{ .reg = .ax } },75472 .{ .type = .f16, .kind = .{ .reg = .ax } },
75655 .unused,75473 .unused,
75656 .unused,75474 .unused,
...@@ -75684,12 +75502,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -75684,12 +75502,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
75684 .{ .type = .f16, .kind = .{ .reg = .ax } },75502 .{ .type = .f16, .kind = .{ .reg = .ax } },
75685 .{ .type = .f32, .kind = .mem },75503 .{ .type = .f32, .kind = .mem },
75686 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },75504 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
75687 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {75505 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
75688 else => unreachable,75506 else => unreachable,
75689 .down => "__floorh",75507 .down => "__floorh",
75690 .up => "__ceilh",75508 .up => "__ceilh",
75691 .zero => "__trunch",75509 .zero => "__trunch",
75692 } } } },75510 } } },
75693 .unused,75511 .unused,
75694 .unused,75512 .unused,
75695 .unused,75513 .unused,
...@@ -75761,12 +75579,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -75761,12 +75579,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
75761 },75579 },
75762 .call_frame = .{ .alignment = .@"16" },75580 .call_frame = .{ .alignment = .@"16" },
75763 .extra_temps = .{75581 .extra_temps = .{
75764 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {75582 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
75765 else => unreachable,75583 else => unreachable,
75766 .down => "floorf",75584 .down => "floorf",
75767 .up => "ceilf",75585 .up => "ceilf",
75768 .zero => "truncf",75586 .zero => "truncf",
75769 } } } },75587 } } },
75770 .unused,75588 .unused,
75771 .unused,75589 .unused,
75772 .unused,75590 .unused,
...@@ -75888,12 +75706,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -75888,12 +75706,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
75888 .extra_temps = .{75706 .extra_temps = .{
75889 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },75707 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
75890 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },75708 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
75891 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {75709 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
75892 else => unreachable,75710 else => unreachable,
75893 .down => "floorf",75711 .down => "floorf",
75894 .up => "ceilf",75712 .up => "ceilf",
75895 .zero => "truncf",75713 .zero => "truncf",
75896 } } } },75714 } } },
75897 .unused,75715 .unused,
75898 .unused,75716 .unused,
75899 .unused,75717 .unused,
...@@ -75923,12 +75741,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -75923,12 +75741,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
75923 .extra_temps = .{75741 .extra_temps = .{
75924 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },75742 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
75925 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },75743 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
75926 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {75744 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
75927 else => unreachable,75745 else => unreachable,
75928 .down => "floorf",75746 .down => "floorf",
75929 .up => "ceilf",75747 .up => "ceilf",
75930 .zero => "truncf",75748 .zero => "truncf",
75931 } } } },75749 } } },
75932 .unused,75750 .unused,
75933 .unused,75751 .unused,
75934 .unused,75752 .unused,
...@@ -75998,12 +75816,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -75998,12 +75816,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
75998 },75816 },
75999 .call_frame = .{ .alignment = .@"16" },75817 .call_frame = .{ .alignment = .@"16" },
76000 .extra_temps = .{75818 .extra_temps = .{
76001 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {75819 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76002 else => unreachable,75820 else => unreachable,
76003 .down => "floor",75821 .down => "floor",
76004 .up => "ceil",75822 .up => "ceil",
76005 .zero => "trunc",75823 .zero => "trunc",
76006 } } } },75824 } } },
76007 .unused,75825 .unused,
76008 .unused,75826 .unused,
76009 .unused,75827 .unused,
...@@ -76125,12 +75943,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76125,12 +75943,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76125 .extra_temps = .{75943 .extra_temps = .{
76126 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },75944 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
76127 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },75945 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
76128 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {75946 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76129 else => unreachable,75947 else => unreachable,
76130 .down => "floor",75948 .down => "floor",
76131 .up => "ceil",75949 .up => "ceil",
76132 .zero => "trunc",75950 .zero => "trunc",
76133 } } } },75951 } } },
76134 .unused,75952 .unused,
76135 .unused,75953 .unused,
76136 .unused,75954 .unused,
...@@ -76160,12 +75978,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76160,12 +75978,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76160 .extra_temps = .{75978 .extra_temps = .{
76161 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },75979 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
76162 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },75980 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
76163 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {75981 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76164 else => unreachable,75982 else => unreachable,
76165 .down => "floor",75983 .down => "floor",
76166 .up => "ceil",75984 .up => "ceil",
76167 .zero => "trunc",75985 .zero => "trunc",
76168 } } } },75986 } } },
76169 .unused,75987 .unused,
76170 .unused,75988 .unused,
76171 .unused,75989 .unused,
...@@ -76195,12 +76013,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76195,12 +76013,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76195 .extra_temps = .{76013 .extra_temps = .{
76196 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },76014 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
76197 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },76015 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
76198 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {76016 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76199 else => unreachable,76017 else => unreachable,
76200 .down => "floor",76018 .down => "floor",
76201 .up => "ceil",76019 .up => "ceil",
76202 .zero => "trunc",76020 .zero => "trunc",
76203 } } } },76021 } } },
76204 .unused,76022 .unused,
76205 .unused,76023 .unused,
76206 .unused,76024 .unused,
...@@ -76231,12 +76049,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76231,12 +76049,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76231 .extra_temps = .{76049 .extra_temps = .{
76232 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },76050 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
76233 .{ .type = .f80, .kind = .{ .frame = .call_frame } },76051 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
76234 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {76052 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76235 else => unreachable,76053 else => unreachable,
76236 .down => "__floorx",76054 .down => "__floorx",
76237 .up => "__ceilx",76055 .up => "__ceilx",
76238 .zero => "__truncx",76056 .zero => "__truncx",
76239 } } } },76057 } } },
76240 .unused,76058 .unused,
76241 .unused,76059 .unused,
76242 .unused,76060 .unused,
...@@ -76263,12 +76081,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76263,12 +76081,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76263 .extra_temps = .{76081 .extra_temps = .{
76264 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },76082 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
76265 .{ .type = .f80, .kind = .{ .frame = .call_frame } },76083 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
76266 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {76084 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76267 else => unreachable,76085 else => unreachable,
76268 .down => "__floorx",76086 .down => "__floorx",
76269 .up => "__ceilx",76087 .up => "__ceilx",
76270 .zero => "__truncx",76088 .zero => "__truncx",
76271 } } } },76089 } } },
76272 .unused,76090 .unused,
76273 .unused,76091 .unused,
76274 .unused,76092 .unused,
...@@ -76295,12 +76113,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76295,12 +76113,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76295 .extra_temps = .{76113 .extra_temps = .{
76296 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },76114 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
76297 .{ .type = .f80, .kind = .{ .frame = .call_frame } },76115 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
76298 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {76116 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76299 else => unreachable,76117 else => unreachable,
76300 .down => "__floorx",76118 .down => "__floorx",
76301 .up => "__ceilx",76119 .up => "__ceilx",
76302 .zero => "__truncx",76120 .zero => "__truncx",
76303 } } } },76121 } } },
76304 .unused,76122 .unused,
76305 .unused,76123 .unused,
76306 .unused,76124 .unused,
...@@ -76328,12 +76146,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76328,12 +76146,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76328 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },76146 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
76329 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },76147 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
76330 .{ .type = .f80, .kind = .{ .frame = .call_frame } },76148 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
76331 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {76149 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76332 else => unreachable,76150 else => unreachable,
76333 .down => "__floorx",76151 .down => "__floorx",
76334 .up => "__ceilx",76152 .up => "__ceilx",
76335 .zero => "__truncx",76153 .zero => "__truncx",
76336 } } } },76154 } } },
76337 .unused,76155 .unused,
76338 .unused,76156 .unused,
76339 .unused,76157 .unused,
...@@ -76365,12 +76183,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76365,12 +76183,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76365 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },76183 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
76366 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },76184 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
76367 .{ .type = .f80, .kind = .{ .frame = .call_frame } },76185 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
76368 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {76186 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76369 else => unreachable,76187 else => unreachable,
76370 .down => "__floorx",76188 .down => "__floorx",
76371 .up => "__ceilx",76189 .up => "__ceilx",
76372 .zero => "__truncx",76190 .zero => "__truncx",
76373 } } } },76191 } } },
76374 .unused,76192 .unused,
76375 .unused,76193 .unused,
76376 .unused,76194 .unused,
...@@ -76402,12 +76220,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76402,12 +76220,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76402 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },76220 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
76403 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },76221 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
76404 .{ .type = .f80, .kind = .{ .frame = .call_frame } },76222 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
76405 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {76223 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76406 else => unreachable,76224 else => unreachable,
76407 .down => "__floorx",76225 .down => "__floorx",
76408 .up => "__ceilx",76226 .up => "__ceilx",
76409 .zero => "__truncx",76227 .zero => "__truncx",
76410 } } } },76228 } } },
76411 .unused,76229 .unused,
76412 .unused,76230 .unused,
76413 .unused,76231 .unused,
...@@ -76436,12 +76254,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76436,12 +76254,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76436 },76254 },
76437 .call_frame = .{ .alignment = .@"16" },76255 .call_frame = .{ .alignment = .@"16" },
76438 .extra_temps = .{76256 .extra_temps = .{
76439 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {76257 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76440 else => unreachable,76258 else => unreachable,
76441 .down => "floorq",76259 .down => "floorq",
76442 .up => "ceilq",76260 .up => "ceilq",
76443 .zero => "truncq",76261 .zero => "truncq",
76444 } } } },76262 } } },
76445 .unused,76263 .unused,
76446 .unused,76264 .unused,
76447 .unused,76265 .unused,
...@@ -76468,12 +76286,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76468,12 +76286,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76468 .extra_temps = .{76286 .extra_temps = .{
76469 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },76287 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
76470 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },76288 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
76471 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {76289 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76472 else => unreachable,76290 else => unreachable,
76473 .down => "floorq",76291 .down => "floorq",
76474 .up => "ceilq",76292 .up => "ceilq",
76475 .zero => "truncq",76293 .zero => "truncq",
76476 } } } },76294 } } },
76477 .unused,76295 .unused,
76478 .unused,76296 .unused,
76479 .unused,76297 .unused,
...@@ -76503,12 +76321,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76503,12 +76321,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76503 .extra_temps = .{76321 .extra_temps = .{
76504 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },76322 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
76505 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },76323 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
76506 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {76324 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76507 else => unreachable,76325 else => unreachable,
76508 .down => "floorq",76326 .down => "floorq",
76509 .up => "ceilq",76327 .up => "ceilq",
76510 .zero => "truncq",76328 .zero => "truncq",
76511 } } } },76329 } } },
76512 .unused,76330 .unused,
76513 .unused,76331 .unused,
76514 .unused,76332 .unused,
...@@ -76538,12 +76356,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76538,12 +76356,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76538 .extra_temps = .{76356 .extra_temps = .{
76539 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },76357 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
76540 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },76358 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
76541 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (direction) {76359 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
76542 else => unreachable,76360 else => unreachable,
76543 .down => "floorq",76361 .down => "floorq",
76544 .up => "ceilq",76362 .up => "ceilq",
76545 .zero => "truncq",76363 .zero => "truncq",
76546 } } } },76364 } } },
76547 .unused,76365 .unused,
76548 .unused,76366 .unused,
76549 .unused,76367 .unused,
...@@ -77175,7 +76993,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -77175,7 +76993,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77175 },76993 },
77176 .call_frame = .{ .alignment = .@"16" },76994 .call_frame = .{ .alignment = .@"16" },
77177 .extra_temps = .{76995 .extra_temps = .{
77178 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },76996 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
77179 .{ .type = .i32, .kind = .{ .reg = .eax } },76997 .{ .type = .i32, .kind = .{ .reg = .eax } },
77180 .unused,76998 .unused,
77181 .unused,76999 .unused,
...@@ -77518,7 +77336,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -77518,7 +77336,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77518 },77336 },
77519 .call_frame = .{ .alignment = .@"16" },77337 .call_frame = .{ .alignment = .@"16" },
77520 .extra_temps = .{77338 .extra_temps = .{
77521 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },77339 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
77522 .{ .type = .i32, .kind = .{ .reg = .eax } },77340 .{ .type = .i32, .kind = .{ .reg = .eax } },
77523 .unused,77341 .unused,
77524 .unused,77342 .unused,
...@@ -77679,7 +77497,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -77679,7 +77497,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77679 },77497 },
77680 .call_frame = .{ .alignment = .@"16" },77498 .call_frame = .{ .alignment = .@"16" },
77681 .extra_temps = .{77499 .extra_temps = .{
77682 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },77500 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
77683 .{ .type = .i32, .kind = .{ .reg = .eax } },77501 .{ .type = .i32, .kind = .{ .reg = .eax } },
77684 .unused,77502 .unused,
77685 .unused,77503 .unused,
...@@ -78046,7 +77864,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -78046,7 +77864,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
78046 },77864 },
78047 .call_frame = .{ .alignment = .@"16" },77865 .call_frame = .{ .alignment = .@"16" },
78048 .extra_temps = .{77866 .extra_temps = .{
78049 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },77867 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
78050 .{ .type = .i32, .kind = .{ .reg = .eax } },77868 .{ .type = .i32, .kind = .{ .reg = .eax } },
78051 .unused,77869 .unused,
78052 .unused,77870 .unused,
...@@ -78715,7 +78533,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -78715,7 +78533,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
78715 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },78533 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
78716 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },78534 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
78717 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },78535 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
78718 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },78536 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
78719 .{ .type = .i32, .kind = .{ .reg = .eax } },78537 .{ .type = .i32, .kind = .{ .reg = .eax } },
78720 .{ .type = .u8, .kind = .{ .reg = .cl } },78538 .{ .type = .u8, .kind = .{ .reg = .cl } },
78721 .{ .type = .u32, .kind = .{ .reg = .edx } },78539 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -78759,7 +78577,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -78759,7 +78577,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
78759 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },78577 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
78760 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },78578 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
78761 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },78579 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
78762 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },78580 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
78763 .{ .type = .i32, .kind = .{ .reg = .eax } },78581 .{ .type = .i32, .kind = .{ .reg = .eax } },
78764 .{ .type = .u8, .kind = .{ .reg = .cl } },78582 .{ .type = .u8, .kind = .{ .reg = .cl } },
78765 .{ .type = .u32, .kind = .{ .reg = .edx } },78583 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -78803,7 +78621,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -78803,7 +78621,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
78803 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },78621 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
78804 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },78622 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
78805 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },78623 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
78806 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },78624 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
78807 .{ .type = .i32, .kind = .{ .reg = .eax } },78625 .{ .type = .i32, .kind = .{ .reg = .eax } },
78808 .{ .type = .u8, .kind = .{ .reg = .cl } },78626 .{ .type = .u8, .kind = .{ .reg = .cl } },
78809 .{ .type = .u32, .kind = .{ .reg = .edx } },78627 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -78848,7 +78666,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -78848,7 +78666,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
78848 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },78666 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
78849 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },78667 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
78850 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },78668 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
78851 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },78669 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
78852 .{ .type = .i32, .kind = .{ .reg = .eax } },78670 .{ .type = .i32, .kind = .{ .reg = .eax } },
78853 .{ .type = .u8, .kind = .{ .reg = .cl } },78671 .{ .type = .u8, .kind = .{ .reg = .cl } },
78854 .{ .type = .u32, .kind = .{ .reg = .edx } },78672 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -78893,7 +78711,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -78893,7 +78711,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
78893 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },78711 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
78894 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },78712 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
78895 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },78713 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
78896 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },78714 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
78897 .{ .type = .i32, .kind = .{ .reg = .eax } },78715 .{ .type = .i32, .kind = .{ .reg = .eax } },
78898 .{ .type = .u8, .kind = .{ .reg = .cl } },78716 .{ .type = .u8, .kind = .{ .reg = .cl } },
78899 .{ .type = .u32, .kind = .{ .reg = .edx } },78717 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -78940,7 +78758,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -78940,7 +78758,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
78940 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },78758 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
78941 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },78759 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
78942 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },78760 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
78943 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },78761 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
78944 .{ .type = .i32, .kind = .{ .reg = .eax } },78762 .{ .type = .i32, .kind = .{ .reg = .eax } },
78945 .{ .type = .u8, .kind = .{ .reg = .cl } },78763 .{ .type = .u8, .kind = .{ .reg = .cl } },
78946 .{ .type = .u32, .kind = .{ .reg = .edx } },78764 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -78987,7 +78805,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -78987,7 +78805,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
78987 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },78805 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
78988 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },78806 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
78989 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },78807 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
78990 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },78808 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
78991 .{ .type = .i32, .kind = .{ .reg = .eax } },78809 .{ .type = .i32, .kind = .{ .reg = .eax } },
78992 .{ .type = .u8, .kind = .{ .reg = .cl } },78810 .{ .type = .u8, .kind = .{ .reg = .cl } },
78993 .{ .type = .u64, .kind = .{ .reg = .rdx } },78811 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -79040,7 +78858,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -79040,7 +78858,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
79040 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },78858 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
79041 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },78859 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
79042 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },78860 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
79043 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },78861 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
79044 .{ .type = .i32, .kind = .{ .reg = .eax } },78862 .{ .type = .i32, .kind = .{ .reg = .eax } },
79045 .{ .type = .u8, .kind = .{ .reg = .cl } },78863 .{ .type = .u8, .kind = .{ .reg = .cl } },
79046 .{ .type = .u64, .kind = .{ .reg = .rdx } },78864 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -79093,7 +78911,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -79093,7 +78911,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
79093 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },78911 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
79094 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },78912 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
79095 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },78913 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
79096 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },78914 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
79097 .{ .type = .i32, .kind = .{ .reg = .eax } },78915 .{ .type = .i32, .kind = .{ .reg = .eax } },
79098 .{ .type = .u8, .kind = .{ .reg = .cl } },78916 .{ .type = .u8, .kind = .{ .reg = .cl } },
79099 .{ .type = .u64, .kind = .{ .reg = .rdx } },78917 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -79147,7 +78965,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -79147,7 +78965,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
79147 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },78965 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
79148 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },78966 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
79149 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },78967 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
79150 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },78968 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
79151 .{ .type = .i32, .kind = .{ .reg = .eax } },78969 .{ .type = .i32, .kind = .{ .reg = .eax } },
79152 .{ .type = .u8, .kind = .{ .reg = .cl } },78970 .{ .type = .u8, .kind = .{ .reg = .cl } },
79153 .{ .type = .u64, .kind = .{ .reg = .rdx } },78971 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -79201,7 +79019,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -79201,7 +79019,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
79201 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },79019 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
79202 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },79020 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
79203 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },79021 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
79204 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },79022 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
79205 .{ .type = .i32, .kind = .{ .reg = .eax } },79023 .{ .type = .i32, .kind = .{ .reg = .eax } },
79206 .{ .type = .u8, .kind = .{ .reg = .cl } },79024 .{ .type = .u8, .kind = .{ .reg = .cl } },
79207 .{ .type = .u64, .kind = .{ .reg = .rdx } },79025 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -79257,7 +79075,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -79257,7 +79075,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
79257 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },79075 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
79258 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },79076 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
79259 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },79077 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
79260 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },79078 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
79261 .{ .type = .i32, .kind = .{ .reg = .eax } },79079 .{ .type = .i32, .kind = .{ .reg = .eax } },
79262 .{ .type = .u8, .kind = .{ .reg = .cl } },79080 .{ .type = .u8, .kind = .{ .reg = .cl } },
79263 .{ .type = .u64, .kind = .{ .reg = .rdx } },79081 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -80084,7 +79902,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80084,7 +79902,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80084 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },79902 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
80085 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },79903 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
80086 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },79904 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
80087 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },79905 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
80088 .{ .type = .i32, .kind = .{ .reg = .eax } },79906 .{ .type = .i32, .kind = .{ .reg = .eax } },
80089 .{ .type = .u8, .kind = .{ .reg = .cl } },79907 .{ .type = .u8, .kind = .{ .reg = .cl } },
80090 .{ .type = .u32, .kind = .{ .reg = .edx } },79908 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -80128,7 +79946,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80128,7 +79946,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80128 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },79946 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
80129 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },79947 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
80130 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },79948 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
80131 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },79949 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
80132 .{ .type = .i32, .kind = .{ .reg = .eax } },79950 .{ .type = .i32, .kind = .{ .reg = .eax } },
80133 .{ .type = .u8, .kind = .{ .reg = .cl } },79951 .{ .type = .u8, .kind = .{ .reg = .cl } },
80134 .{ .type = .u32, .kind = .{ .reg = .edx } },79952 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -80172,7 +79990,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80172,7 +79990,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80172 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },79990 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
80173 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },79991 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
80174 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },79992 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
80175 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },79993 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
80176 .{ .type = .i32, .kind = .{ .reg = .eax } },79994 .{ .type = .i32, .kind = .{ .reg = .eax } },
80177 .{ .type = .u8, .kind = .{ .reg = .cl } },79995 .{ .type = .u8, .kind = .{ .reg = .cl } },
80178 .{ .type = .u32, .kind = .{ .reg = .edx } },79996 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -80216,7 +80034,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80216,7 +80034,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80216 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },80034 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
80217 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },80035 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
80218 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },80036 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
80219 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },80037 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
80220 .{ .type = .i32, .kind = .{ .reg = .eax } },80038 .{ .type = .i32, .kind = .{ .reg = .eax } },
80221 .{ .type = .u8, .kind = .{ .reg = .cl } },80039 .{ .type = .u8, .kind = .{ .reg = .cl } },
80222 .{ .type = .u32, .kind = .{ .reg = .edx } },80040 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -80260,7 +80078,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80260,7 +80078,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80260 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },80078 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
80261 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },80079 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
80262 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },80080 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
80263 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },80081 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
80264 .{ .type = .i32, .kind = .{ .reg = .eax } },80082 .{ .type = .i32, .kind = .{ .reg = .eax } },
80265 .{ .type = .u8, .kind = .{ .reg = .cl } },80083 .{ .type = .u8, .kind = .{ .reg = .cl } },
80266 .{ .type = .u32, .kind = .{ .reg = .edx } },80084 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -80304,7 +80122,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80304,7 +80122,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80304 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },80122 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
80305 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },80123 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
80306 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },80124 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
80307 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },80125 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
80308 .{ .type = .i32, .kind = .{ .reg = .eax } },80126 .{ .type = .i32, .kind = .{ .reg = .eax } },
80309 .{ .type = .u8, .kind = .{ .reg = .cl } },80127 .{ .type = .u8, .kind = .{ .reg = .cl } },
80310 .{ .type = .u32, .kind = .{ .reg = .edx } },80128 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -80348,7 +80166,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80348,7 +80166,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80348 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },80166 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
80349 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },80167 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
80350 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },80168 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
80351 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },80169 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
80352 .{ .type = .i32, .kind = .{ .reg = .eax } },80170 .{ .type = .i32, .kind = .{ .reg = .eax } },
80353 .{ .type = .u8, .kind = .{ .reg = .cl } },80171 .{ .type = .u8, .kind = .{ .reg = .cl } },
80354 .{ .type = .u64, .kind = .{ .reg = .rdx } },80172 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -80401,7 +80219,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80401,7 +80219,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80401 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },80219 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
80402 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },80220 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
80403 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },80221 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
80404 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },80222 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
80405 .{ .type = .i32, .kind = .{ .reg = .eax } },80223 .{ .type = .i32, .kind = .{ .reg = .eax } },
80406 .{ .type = .u8, .kind = .{ .reg = .cl } },80224 .{ .type = .u8, .kind = .{ .reg = .cl } },
80407 .{ .type = .u64, .kind = .{ .reg = .rdx } },80225 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -80454,7 +80272,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80454,7 +80272,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80454 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },80272 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
80455 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },80273 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
80456 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },80274 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
80457 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },80275 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
80458 .{ .type = .i32, .kind = .{ .reg = .eax } },80276 .{ .type = .i32, .kind = .{ .reg = .eax } },
80459 .{ .type = .u8, .kind = .{ .reg = .cl } },80277 .{ .type = .u8, .kind = .{ .reg = .cl } },
80460 .{ .type = .u64, .kind = .{ .reg = .rdx } },80278 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -80507,7 +80325,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80507,7 +80325,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80507 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },80325 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
80508 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },80326 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
80509 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },80327 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
80510 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },80328 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
80511 .{ .type = .i32, .kind = .{ .reg = .eax } },80329 .{ .type = .i32, .kind = .{ .reg = .eax } },
80512 .{ .type = .u8, .kind = .{ .reg = .cl } },80330 .{ .type = .u8, .kind = .{ .reg = .cl } },
80513 .{ .type = .u64, .kind = .{ .reg = .rdx } },80331 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -80560,7 +80378,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80560,7 +80378,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80560 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },80378 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
80561 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },80379 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
80562 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },80380 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
80563 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },80381 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
80564 .{ .type = .i32, .kind = .{ .reg = .eax } },80382 .{ .type = .i32, .kind = .{ .reg = .eax } },
80565 .{ .type = .u8, .kind = .{ .reg = .cl } },80383 .{ .type = .u8, .kind = .{ .reg = .cl } },
80566 .{ .type = .u64, .kind = .{ .reg = .rdx } },80384 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -80613,7 +80431,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80613,7 +80431,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80613 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },80431 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
80614 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },80432 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
80615 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },80433 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
80616 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },80434 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
80617 .{ .type = .i32, .kind = .{ .reg = .eax } },80435 .{ .type = .i32, .kind = .{ .reg = .eax } },
80618 .{ .type = .u8, .kind = .{ .reg = .cl } },80436 .{ .type = .u8, .kind = .{ .reg = .cl } },
80619 .{ .type = .u64, .kind = .{ .reg = .rdx } },80437 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -83223,7 +83041,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -83223,7 +83041,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
83223 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },83041 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
83224 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },83042 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
83225 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },83043 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
83226 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },83044 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
83227 .{ .type = .i32, .kind = .{ .reg = .eax } },83045 .{ .type = .i32, .kind = .{ .reg = .eax } },
83228 .{ .type = .u8, .kind = .{ .reg = .cl } },83046 .{ .type = .u8, .kind = .{ .reg = .cl } },
83229 .{ .type = .u32, .kind = .{ .reg = .edx } },83047 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -83267,7 +83085,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -83267,7 +83085,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
83267 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },83085 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
83268 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },83086 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
83269 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },83087 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
83270 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },83088 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
83271 .{ .type = .i32, .kind = .{ .reg = .eax } },83089 .{ .type = .i32, .kind = .{ .reg = .eax } },
83272 .{ .type = .u8, .kind = .{ .reg = .cl } },83090 .{ .type = .u8, .kind = .{ .reg = .cl } },
83273 .{ .type = .u32, .kind = .{ .reg = .edx } },83091 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -83311,7 +83129,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -83311,7 +83129,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
83311 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },83129 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
83312 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },83130 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
83313 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },83131 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
83314 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },83132 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
83315 .{ .type = .i32, .kind = .{ .reg = .eax } },83133 .{ .type = .i32, .kind = .{ .reg = .eax } },
83316 .{ .type = .u8, .kind = .{ .reg = .cl } },83134 .{ .type = .u8, .kind = .{ .reg = .cl } },
83317 .{ .type = .u32, .kind = .{ .reg = .edx } },83135 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -83356,7 +83174,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -83356,7 +83174,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
83356 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },83174 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
83357 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },83175 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
83358 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },83176 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
83359 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },83177 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
83360 .{ .type = .i32, .kind = .{ .reg = .eax } },83178 .{ .type = .i32, .kind = .{ .reg = .eax } },
83361 .{ .type = .u8, .kind = .{ .reg = .cl } },83179 .{ .type = .u8, .kind = .{ .reg = .cl } },
83362 .{ .type = .u32, .kind = .{ .reg = .edx } },83180 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -83401,7 +83219,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -83401,7 +83219,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
83401 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },83219 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
83402 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },83220 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
83403 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },83221 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
83404 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },83222 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
83405 .{ .type = .i32, .kind = .{ .reg = .eax } },83223 .{ .type = .i32, .kind = .{ .reg = .eax } },
83406 .{ .type = .u8, .kind = .{ .reg = .cl } },83224 .{ .type = .u8, .kind = .{ .reg = .cl } },
83407 .{ .type = .u32, .kind = .{ .reg = .edx } },83225 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -83448,7 +83266,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -83448,7 +83266,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
83448 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },83266 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
83449 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },83267 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
83450 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },83268 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
83451 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },83269 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
83452 .{ .type = .i32, .kind = .{ .reg = .eax } },83270 .{ .type = .i32, .kind = .{ .reg = .eax } },
83453 .{ .type = .u8, .kind = .{ .reg = .cl } },83271 .{ .type = .u8, .kind = .{ .reg = .cl } },
83454 .{ .type = .u32, .kind = .{ .reg = .edx } },83272 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -83495,7 +83313,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -83495,7 +83313,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
83495 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },83313 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
83496 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },83314 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
83497 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },83315 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
83498 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },83316 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
83499 .{ .type = .i32, .kind = .{ .reg = .eax } },83317 .{ .type = .i32, .kind = .{ .reg = .eax } },
83500 .{ .type = .u8, .kind = .{ .reg = .cl } },83318 .{ .type = .u8, .kind = .{ .reg = .cl } },
83501 .{ .type = .u64, .kind = .{ .reg = .rdx } },83319 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -83548,7 +83366,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -83548,7 +83366,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
83548 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },83366 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
83549 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },83367 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
83550 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },83368 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
83551 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },83369 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
83552 .{ .type = .i32, .kind = .{ .reg = .eax } },83370 .{ .type = .i32, .kind = .{ .reg = .eax } },
83553 .{ .type = .u8, .kind = .{ .reg = .cl } },83371 .{ .type = .u8, .kind = .{ .reg = .cl } },
83554 .{ .type = .u64, .kind = .{ .reg = .rdx } },83372 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -83601,7 +83419,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -83601,7 +83419,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
83601 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },83419 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
83602 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },83420 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
83603 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },83421 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
83604 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },83422 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
83605 .{ .type = .i32, .kind = .{ .reg = .eax } },83423 .{ .type = .i32, .kind = .{ .reg = .eax } },
83606 .{ .type = .u8, .kind = .{ .reg = .cl } },83424 .{ .type = .u8, .kind = .{ .reg = .cl } },
83607 .{ .type = .u64, .kind = .{ .reg = .rdx } },83425 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -83655,7 +83473,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -83655,7 +83473,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
83655 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },83473 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
83656 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },83474 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
83657 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },83475 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
83658 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },83476 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
83659 .{ .type = .i32, .kind = .{ .reg = .eax } },83477 .{ .type = .i32, .kind = .{ .reg = .eax } },
83660 .{ .type = .u8, .kind = .{ .reg = .cl } },83478 .{ .type = .u8, .kind = .{ .reg = .cl } },
83661 .{ .type = .u64, .kind = .{ .reg = .rdx } },83479 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -83709,7 +83527,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -83709,7 +83527,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
83709 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },83527 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
83710 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },83528 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
83711 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },83529 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
83712 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },83530 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
83713 .{ .type = .i32, .kind = .{ .reg = .eax } },83531 .{ .type = .i32, .kind = .{ .reg = .eax } },
83714 .{ .type = .u8, .kind = .{ .reg = .cl } },83532 .{ .type = .u8, .kind = .{ .reg = .cl } },
83715 .{ .type = .u64, .kind = .{ .reg = .rdx } },83533 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -83765,7 +83583,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -83765,7 +83583,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
83765 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },83583 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
83766 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },83584 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
83767 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },83585 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
83768 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } },83586 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
83769 .{ .type = .i32, .kind = .{ .reg = .eax } },83587 .{ .type = .i32, .kind = .{ .reg = .eax } },
83770 .{ .type = .u8, .kind = .{ .reg = .cl } },83588 .{ .type = .u8, .kind = .{ .reg = .cl } },
83771 .{ .type = .u64, .kind = .{ .reg = .rdx } },83589 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -84606,7 +84424,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -84606,7 +84424,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
84606 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },84424 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
84607 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },84425 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
84608 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },84426 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
84609 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },84427 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
84610 .{ .type = .i32, .kind = .{ .reg = .eax } },84428 .{ .type = .i32, .kind = .{ .reg = .eax } },
84611 .{ .type = .u8, .kind = .{ .reg = .cl } },84429 .{ .type = .u8, .kind = .{ .reg = .cl } },
84612 .{ .type = .u32, .kind = .{ .reg = .edx } },84430 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -84650,7 +84468,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -84650,7 +84468,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
84650 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },84468 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
84651 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },84469 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
84652 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },84470 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
84653 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },84471 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
84654 .{ .type = .i32, .kind = .{ .reg = .eax } },84472 .{ .type = .i32, .kind = .{ .reg = .eax } },
84655 .{ .type = .u8, .kind = .{ .reg = .cl } },84473 .{ .type = .u8, .kind = .{ .reg = .cl } },
84656 .{ .type = .u32, .kind = .{ .reg = .edx } },84474 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -84694,7 +84512,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -84694,7 +84512,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
84694 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },84512 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
84695 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },84513 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
84696 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },84514 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
84697 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },84515 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
84698 .{ .type = .i32, .kind = .{ .reg = .eax } },84516 .{ .type = .i32, .kind = .{ .reg = .eax } },
84699 .{ .type = .u8, .kind = .{ .reg = .cl } },84517 .{ .type = .u8, .kind = .{ .reg = .cl } },
84700 .{ .type = .u32, .kind = .{ .reg = .edx } },84518 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -84738,7 +84556,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -84738,7 +84556,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
84738 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },84556 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
84739 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },84557 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
84740 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },84558 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
84741 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },84559 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
84742 .{ .type = .i32, .kind = .{ .reg = .eax } },84560 .{ .type = .i32, .kind = .{ .reg = .eax } },
84743 .{ .type = .u8, .kind = .{ .reg = .cl } },84561 .{ .type = .u8, .kind = .{ .reg = .cl } },
84744 .{ .type = .u32, .kind = .{ .reg = .edx } },84562 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -84782,7 +84600,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -84782,7 +84600,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
84782 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },84600 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
84783 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },84601 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
84784 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },84602 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
84785 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },84603 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
84786 .{ .type = .i32, .kind = .{ .reg = .eax } },84604 .{ .type = .i32, .kind = .{ .reg = .eax } },
84787 .{ .type = .u8, .kind = .{ .reg = .cl } },84605 .{ .type = .u8, .kind = .{ .reg = .cl } },
84788 .{ .type = .u32, .kind = .{ .reg = .edx } },84606 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -84826,7 +84644,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -84826,7 +84644,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
84826 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },84644 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
84827 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },84645 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
84828 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },84646 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
84829 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },84647 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
84830 .{ .type = .i32, .kind = .{ .reg = .eax } },84648 .{ .type = .i32, .kind = .{ .reg = .eax } },
84831 .{ .type = .u8, .kind = .{ .reg = .cl } },84649 .{ .type = .u8, .kind = .{ .reg = .cl } },
84832 .{ .type = .u32, .kind = .{ .reg = .edx } },84650 .{ .type = .u32, .kind = .{ .reg = .edx } },
...@@ -84870,7 +84688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -84870,7 +84688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
84870 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },84688 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
84871 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },84689 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
84872 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },84690 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
84873 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },84691 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
84874 .{ .type = .i32, .kind = .{ .reg = .eax } },84692 .{ .type = .i32, .kind = .{ .reg = .eax } },
84875 .{ .type = .u8, .kind = .{ .reg = .cl } },84693 .{ .type = .u8, .kind = .{ .reg = .cl } },
84876 .{ .type = .u64, .kind = .{ .reg = .rdx } },84694 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -84923,7 +84741,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -84923,7 +84741,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
84923 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },84741 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
84924 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },84742 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
84925 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },84743 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
84926 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },84744 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
84927 .{ .type = .i32, .kind = .{ .reg = .eax } },84745 .{ .type = .i32, .kind = .{ .reg = .eax } },
84928 .{ .type = .u8, .kind = .{ .reg = .cl } },84746 .{ .type = .u8, .kind = .{ .reg = .cl } },
84929 .{ .type = .u64, .kind = .{ .reg = .rdx } },84747 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -84976,7 +84794,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -84976,7 +84794,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
84976 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },84794 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
84977 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },84795 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
84978 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },84796 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
84979 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },84797 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
84980 .{ .type = .i32, .kind = .{ .reg = .eax } },84798 .{ .type = .i32, .kind = .{ .reg = .eax } },
84981 .{ .type = .u8, .kind = .{ .reg = .cl } },84799 .{ .type = .u8, .kind = .{ .reg = .cl } },
84982 .{ .type = .u64, .kind = .{ .reg = .rdx } },84800 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -85029,7 +84847,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85029,7 +84847,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85029 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },84847 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
85030 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },84848 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
85031 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },84849 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
85032 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },84850 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
85033 .{ .type = .i32, .kind = .{ .reg = .eax } },84851 .{ .type = .i32, .kind = .{ .reg = .eax } },
85034 .{ .type = .u8, .kind = .{ .reg = .cl } },84852 .{ .type = .u8, .kind = .{ .reg = .cl } },
85035 .{ .type = .u64, .kind = .{ .reg = .rdx } },84853 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -85082,7 +84900,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85082,7 +84900,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85082 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },84900 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
85083 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },84901 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
85084 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },84902 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
85085 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },84903 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
85086 .{ .type = .i32, .kind = .{ .reg = .eax } },84904 .{ .type = .i32, .kind = .{ .reg = .eax } },
85087 .{ .type = .u8, .kind = .{ .reg = .cl } },84905 .{ .type = .u8, .kind = .{ .reg = .cl } },
85088 .{ .type = .u64, .kind = .{ .reg = .rdx } },84906 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -85135,7 +84953,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85135,7 +84953,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85135 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },84953 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
85136 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },84954 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
85137 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },84955 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
85138 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } },84956 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
85139 .{ .type = .i32, .kind = .{ .reg = .eax } },84957 .{ .type = .i32, .kind = .{ .reg = .eax } },
85140 .{ .type = .u8, .kind = .{ .reg = .cl } },84958 .{ .type = .u8, .kind = .{ .reg = .cl } },
85141 .{ .type = .u64, .kind = .{ .reg = .rdx } },84959 .{ .type = .u64, .kind = .{ .reg = .rdx } },
...@@ -85191,7 +85009,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85191,7 +85009,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85191 .switch_dispatch => try cg.airSwitchDispatch(inst),85009 .switch_dispatch => try cg.airSwitchDispatch(inst),
85192 .@"try", .try_cold => try cg.airTry(inst),85010 .@"try", .try_cold => try cg.airTry(inst),
85193 .try_ptr, .try_ptr_cold => try cg.airTryPtr(inst),85011 .try_ptr, .try_ptr_cold => try cg.airTryPtr(inst),
85194 .dbg_stmt => if (cg.debug_output != .none) {85012 .dbg_stmt => if (!cg.mod.strip) {
85195 const dbg_stmt = air_datas[@intFromEnum(inst)].dbg_stmt;85013 const dbg_stmt = air_datas[@intFromEnum(inst)].dbg_stmt;
85196 _ = try cg.addInst(.{85014 _ = try cg.addInst(.{
85197 .tag = .pseudo,85015 .tag = .pseudo,
...@@ -85202,7 +85020,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85202,7 +85020,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85202 } },85020 } },
85203 });85021 });
85204 },85022 },
85205 .dbg_empty_stmt => if (cg.debug_output != .none) {85023 .dbg_empty_stmt => if (!cg.mod.strip) {
85206 if (cg.mir_instructions.len > 0) {85024 if (cg.mir_instructions.len > 0) {
85207 const prev_mir_op = &cg.mir_instructions.items(.ops)[cg.mir_instructions.len - 1];85025 const prev_mir_op = &cg.mir_instructions.items(.ops)[cg.mir_instructions.len - 1];
85208 if (prev_mir_op.* == .pseudo_dbg_line_line_column)85026 if (prev_mir_op.* == .pseudo_dbg_line_line_column)
...@@ -85216,23 +85034,27 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85216,23 +85034,27 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85216 const old_inline_func = cg.inline_func;85034 const old_inline_func = cg.inline_func;
85217 defer cg.inline_func = old_inline_func;85035 defer cg.inline_func = old_inline_func;
85218 cg.inline_func = dbg_inline_block.data.func;85036 cg.inline_func = dbg_inline_block.data.func;
85219 if (cg.debug_output != .none) _ = try cg.addInst(.{85037 if (!cg.mod.strip) _ = try cg.addInst(.{
85220 .tag = .pseudo,85038 .tag = .pseudo,
85221 .ops = .pseudo_dbg_enter_inline_func,85039 .ops = .pseudo_dbg_enter_inline_func,
85222 .data = .{ .func = dbg_inline_block.data.func },85040 .data = .{ .ip_index = dbg_inline_block.data.func },
85223 });85041 });
85224 try cg.lowerBlock(inst, @ptrCast(cg.air.extra.items[dbg_inline_block.end..][0..dbg_inline_block.data.body_len]));85042 try cg.lowerBlock(inst, @ptrCast(cg.air.extra.items[dbg_inline_block.end..][0..dbg_inline_block.data.body_len]));
85225 if (cg.debug_output != .none) _ = try cg.addInst(.{85043 if (!cg.mod.strip) _ = try cg.addInst(.{
85226 .tag = .pseudo,85044 .tag = .pseudo,
85227 .ops = .pseudo_dbg_leave_inline_func,85045 .ops = .pseudo_dbg_leave_inline_func,
85228 .data = .{ .func = old_inline_func },85046 .data = .{ .ip_index = old_inline_func },
85229 });85047 });
85230 },85048 },
85231 .dbg_var_ptr,85049 .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => |air_tag| if (use_old) try cg.airDbgVar(inst) else if (!cg.mod.strip) {
85232 .dbg_var_val,
85233 .dbg_arg_inline,
85234 => if (use_old) try cg.airDbgVar(inst) else if (cg.debug_output != .none) {
85235 const pl_op = air_datas[@intFromEnum(inst)].pl_op;85050 const pl_op = air_datas[@intFromEnum(inst)].pl_op;
85051 const air_name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
85052 const op_ty = cg.typeOf(pl_op.operand);
85053 const local_ty = switch (air_tag) {
85054 else => unreachable,
85055 .dbg_var_ptr => op_ty.childType(zcu),
85056 .dbg_var_val, .dbg_arg_inline => op_ty,
85057 };
85236 var ops = try cg.tempsFromOperands(inst, .{pl_op.operand});85058 var ops = try cg.tempsFromOperands(inst, .{pl_op.operand});
85237 var mcv = ops[0].tracking(cg).short;85059 var mcv = ops[0].tracking(cg).short;
85238 switch (mcv) {85060 switch (mcv) {
...@@ -85247,7 +85069,19 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85247,7 +85069,19 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85247 },85069 },
85248 },85070 },
85249 }85071 }
85250 try cg.genLocalDebugInfo(inst, ops[0].tracking(cg).short);85072
85073 try cg.mir_locals.append(cg.gpa, .{
85074 .name = switch (air_name) {
85075 .none => switch (air_tag) {
85076 else => unreachable,
85077 .dbg_arg_inline => .none,
85078 },
85079 else => try cg.addString(air_name.toSlice(cg.air)),
85080 },
85081 .type = local_ty.toIntern(),
85082 });
85083
85084 try cg.genLocalDebugInfo(air_tag, local_ty, ops[0].tracking(cg).short);
85251 try ops[0].die(cg);85085 try ops[0].die(cg);
85252 },85086 },
85253 .is_null => if (use_old) try cg.airIsNull(inst) else {85087 .is_null => if (use_old) try cg.airIsNull(inst) else {
...@@ -85435,11 +85269,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85435,11 +85269,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85435 .ret => try cg.airRet(inst, false),85269 .ret => try cg.airRet(inst, false),
85436 .ret_safe => try cg.airRet(inst, true),85270 .ret_safe => try cg.airRet(inst, true),
85437 .ret_load => try cg.airRetLoad(inst),85271 .ret_load => try cg.airRetLoad(inst),
85438 .store, .store_safe => |air_tag| if (use_old) try cg.airStore(inst, switch (air_tag) {85272 .store, .store_safe => |air_tag| fallback: {
85439 else => unreachable,
85440 .store => false,
85441 .store_safe => true,
85442 }) else fallback: {
85443 const bin_op = air_datas[@intFromEnum(inst)].bin_op;85273 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
85444 const ptr_ty = cg.typeOf(bin_op.lhs);85274 const ptr_ty = cg.typeOf(bin_op.lhs);
85445 const ptr_info = ptr_ty.ptrInfo(zcu);85275 const ptr_info = ptr_ty.ptrInfo(zcu);
...@@ -85513,7 +85343,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85513,7 +85343,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85513 },85343 },
85514 .call_frame = .{ .alignment = .@"16" },85344 .call_frame = .{ .alignment = .@"16" },
85515 .extra_temps = .{85345 .extra_temps = .{
85516 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncsfhf2" } } },85346 .{ .type = .usize, .kind = .{ .extern_func = "__truncsfhf2" } },
85517 .unused,85347 .unused,
85518 .unused,85348 .unused,
85519 .unused,85349 .unused,
...@@ -85570,7 +85400,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85570,7 +85400,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85570 .extra_temps = .{85400 .extra_temps = .{
85571 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },85401 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
85572 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },85402 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
85573 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncsfhf2" } } },85403 .{ .type = .usize, .kind = .{ .extern_func = "__truncsfhf2" } },
85574 .unused,85404 .unused,
85575 .unused,85405 .unused,
85576 .unused,85406 .unused,
...@@ -85601,7 +85431,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85601,7 +85431,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85601 .extra_temps = .{85431 .extra_temps = .{
85602 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },85432 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
85603 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },85433 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
85604 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncsfhf2" } } },85434 .{ .type = .usize, .kind = .{ .extern_func = "__truncsfhf2" } },
85605 .unused,85435 .unused,
85606 .unused,85436 .unused,
85607 .unused,85437 .unused,
...@@ -85632,7 +85462,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85632,7 +85462,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85632 .extra_temps = .{85462 .extra_temps = .{
85633 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },85463 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
85634 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },85464 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
85635 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncsfhf2" } } },85465 .{ .type = .usize, .kind = .{ .extern_func = "__truncsfhf2" } },
85636 .{ .type = .f16, .kind = .{ .reg = .ax } },85466 .{ .type = .f16, .kind = .{ .reg = .ax } },
85637 .unused,85467 .unused,
85638 .unused,85468 .unused,
...@@ -85664,7 +85494,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85664,7 +85494,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85664 .extra_temps = .{85494 .extra_temps = .{
85665 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },85495 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
85666 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },85496 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
85667 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncsfhf2" } } },85497 .{ .type = .usize, .kind = .{ .extern_func = "__truncsfhf2" } },
85668 .{ .type = .f32, .kind = .mem },85498 .{ .type = .f32, .kind = .mem },
85669 .{ .type = .f16, .kind = .{ .reg = .ax } },85499 .{ .type = .f16, .kind = .{ .reg = .ax } },
85670 .unused,85500 .unused,
...@@ -85695,7 +85525,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85695,7 +85525,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85695 },85525 },
85696 .call_frame = .{ .alignment = .@"16" },85526 .call_frame = .{ .alignment = .@"16" },
85697 .extra_temps = .{85527 .extra_temps = .{
85698 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncdfhf2" } } },85528 .{ .type = .usize, .kind = .{ .extern_func = "__truncdfhf2" } },
85699 .unused,85529 .unused,
85700 .unused,85530 .unused,
85701 .unused,85531 .unused,
...@@ -85723,7 +85553,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85723,7 +85553,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85723 .extra_temps = .{85553 .extra_temps = .{
85724 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },85554 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
85725 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },85555 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
85726 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncdfhf2" } } },85556 .{ .type = .usize, .kind = .{ .extern_func = "__truncdfhf2" } },
85727 .unused,85557 .unused,
85728 .unused,85558 .unused,
85729 .unused,85559 .unused,
...@@ -85754,7 +85584,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85754,7 +85584,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85754 .extra_temps = .{85584 .extra_temps = .{
85755 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },85585 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
85756 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },85586 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
85757 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncdfhf2" } } },85587 .{ .type = .usize, .kind = .{ .extern_func = "__truncdfhf2" } },
85758 .unused,85588 .unused,
85759 .unused,85589 .unused,
85760 .unused,85590 .unused,
...@@ -85785,7 +85615,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85785,7 +85615,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85785 .extra_temps = .{85615 .extra_temps = .{
85786 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },85616 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
85787 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },85617 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
85788 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncdfhf2" } } },85618 .{ .type = .usize, .kind = .{ .extern_func = "__truncdfhf2" } },
85789 .{ .type = .f16, .kind = .{ .reg = .ax } },85619 .{ .type = .f16, .kind = .{ .reg = .ax } },
85790 .unused,85620 .unused,
85791 .unused,85621 .unused,
...@@ -85817,7 +85647,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85817,7 +85647,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85817 .extra_temps = .{85647 .extra_temps = .{
85818 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },85648 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
85819 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },85649 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
85820 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncdfhf2" } } },85650 .{ .type = .usize, .kind = .{ .extern_func = "__truncdfhf2" } },
85821 .{ .type = .f32, .kind = .mem },85651 .{ .type = .f32, .kind = .mem },
85822 .{ .type = .f16, .kind = .{ .reg = .ax } },85652 .{ .type = .f16, .kind = .{ .reg = .ax } },
85823 .unused,85653 .unused,
...@@ -86034,7 +85864,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86034,7 +85864,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86034 .call_frame = .{ .size = 16, .alignment = .@"16" },85864 .call_frame = .{ .size = 16, .alignment = .@"16" },
86035 .extra_temps = .{85865 .extra_temps = .{
86036 .{ .type = .f80, .kind = .{ .frame = .call_frame } },85866 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
86037 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncxfhf2" } } },85867 .{ .type = .usize, .kind = .{ .extern_func = "__truncxfhf2" } },
86038 .unused,85868 .unused,
86039 .unused,85869 .unused,
86040 .unused,85870 .unused,
...@@ -86062,7 +85892,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86062,7 +85892,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86062 .call_frame = .{ .size = 16, .alignment = .@"16" },85892 .call_frame = .{ .size = 16, .alignment = .@"16" },
86063 .extra_temps = .{85893 .extra_temps = .{
86064 .{ .type = .f80, .kind = .{ .frame = .call_frame } },85894 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
86065 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncxfhf2" } } },85895 .{ .type = .usize, .kind = .{ .extern_func = "__truncxfhf2" } },
86066 .unused,85896 .unused,
86067 .unused,85897 .unused,
86068 .unused,85898 .unused,
...@@ -86090,7 +85920,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86090,7 +85920,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86090 .call_frame = .{ .size = 16, .alignment = .@"16" },85920 .call_frame = .{ .size = 16, .alignment = .@"16" },
86091 .extra_temps = .{85921 .extra_temps = .{
86092 .{ .type = .f80, .kind = .{ .frame = .call_frame } },85922 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
86093 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncxfhf2" } } },85923 .{ .type = .usize, .kind = .{ .extern_func = "__truncxfhf2" } },
86094 .unused,85924 .unused,
86095 .unused,85925 .unused,
86096 .unused,85926 .unused,
...@@ -86120,7 +85950,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86120,7 +85950,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86120 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },85950 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86121 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },85951 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
86122 .{ .type = .f80, .kind = .{ .frame = .call_frame } },85952 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
86123 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncxfhf2" } } },85953 .{ .type = .usize, .kind = .{ .extern_func = "__truncxfhf2" } },
86124 .unused,85954 .unused,
86125 .unused,85955 .unused,
86126 .unused,85956 .unused,
...@@ -86152,7 +85982,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86152,7 +85982,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86152 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },85982 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86153 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },85983 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
86154 .{ .type = .f80, .kind = .{ .frame = .call_frame } },85984 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
86155 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncxfhf2" } } },85985 .{ .type = .usize, .kind = .{ .extern_func = "__truncxfhf2" } },
86156 .unused,85986 .unused,
86157 .unused,85987 .unused,
86158 .unused,85988 .unused,
...@@ -86184,7 +86014,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86184,7 +86014,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86184 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86014 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86185 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },86015 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
86186 .{ .type = .f80, .kind = .{ .frame = .call_frame } },86016 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
86187 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncxfhf2" } } },86017 .{ .type = .usize, .kind = .{ .extern_func = "__truncxfhf2" } },
86188 .{ .type = .f16, .kind = .{ .reg = .ax } },86018 .{ .type = .f16, .kind = .{ .reg = .ax } },
86189 .unused,86019 .unused,
86190 .unused,86020 .unused,
...@@ -86217,7 +86047,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86217,7 +86047,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86217 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86047 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86218 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },86048 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
86219 .{ .type = .f80, .kind = .{ .frame = .call_frame } },86049 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
86220 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__truncxfhf2" } } },86050 .{ .type = .usize, .kind = .{ .extern_func = "__truncxfhf2" } },
86221 .{ .type = .f16, .kind = .{ .reg = .ax } },86051 .{ .type = .f16, .kind = .{ .reg = .ax } },
86222 .unused,86052 .unused,
86223 .unused,86053 .unused,
...@@ -86358,7 +86188,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86358,7 +86188,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86358 },86188 },
86359 .call_frame = .{ .alignment = .@"16" },86189 .call_frame = .{ .alignment = .@"16" },
86360 .extra_temps = .{86190 .extra_temps = .{
86361 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfhf2" } } },86191 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfhf2" } },
86362 .unused,86192 .unused,
86363 .unused,86193 .unused,
86364 .unused,86194 .unused,
...@@ -86386,7 +86216,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86386,7 +86216,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86386 .extra_temps = .{86216 .extra_temps = .{
86387 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86217 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86388 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },86218 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
86389 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfhf2" } } },86219 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfhf2" } },
86390 .unused,86220 .unused,
86391 .unused,86221 .unused,
86392 .unused,86222 .unused,
...@@ -86417,7 +86247,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86417,7 +86247,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86417 .extra_temps = .{86247 .extra_temps = .{
86418 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86248 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86419 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },86249 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
86420 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfhf2" } } },86250 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfhf2" } },
86421 .unused,86251 .unused,
86422 .unused,86252 .unused,
86423 .unused,86253 .unused,
...@@ -86448,7 +86278,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86448,7 +86278,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86448 .extra_temps = .{86278 .extra_temps = .{
86449 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86279 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86450 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },86280 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
86451 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfhf2" } } },86281 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfhf2" } },
86452 .{ .type = .f16, .kind = .{ .reg = .ax } },86282 .{ .type = .f16, .kind = .{ .reg = .ax } },
86453 .unused,86283 .unused,
86454 .unused,86284 .unused,
...@@ -86480,7 +86310,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86480,7 +86310,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86480 .extra_temps = .{86310 .extra_temps = .{
86481 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86311 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86482 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },86312 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
86483 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfhf2" } } },86313 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfhf2" } },
86484 .{ .type = .f32, .kind = .mem },86314 .{ .type = .f32, .kind = .mem },
86485 .{ .type = .f16, .kind = .{ .reg = .ax } },86315 .{ .type = .f16, .kind = .{ .reg = .ax } },
86486 .unused,86316 .unused,
...@@ -86511,7 +86341,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86511,7 +86341,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86511 },86341 },
86512 .call_frame = .{ .alignment = .@"16" },86342 .call_frame = .{ .alignment = .@"16" },
86513 .extra_temps = .{86343 .extra_temps = .{
86514 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfsf2" } } },86344 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfsf2" } },
86515 .unused,86345 .unused,
86516 .unused,86346 .unused,
86517 .unused,86347 .unused,
...@@ -86539,7 +86369,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86539,7 +86369,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86539 .extra_temps = .{86369 .extra_temps = .{
86540 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86370 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86541 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },86371 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
86542 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfsf2" } } },86372 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfsf2" } },
86543 .unused,86373 .unused,
86544 .unused,86374 .unused,
86545 .unused,86375 .unused,
...@@ -86570,7 +86400,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86570,7 +86400,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86570 .extra_temps = .{86400 .extra_temps = .{
86571 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86401 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86572 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },86402 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
86573 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfsf2" } } },86403 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfsf2" } },
86574 .unused,86404 .unused,
86575 .unused,86405 .unused,
86576 .unused,86406 .unused,
...@@ -86601,7 +86431,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86601,7 +86431,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86601 .extra_temps = .{86431 .extra_temps = .{
86602 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86432 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86603 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },86433 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
86604 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfsf2" } } },86434 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfsf2" } },
86605 .unused,86435 .unused,
86606 .unused,86436 .unused,
86607 .unused,86437 .unused,
...@@ -86630,7 +86460,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86630,7 +86460,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86630 },86460 },
86631 .call_frame = .{ .alignment = .@"16" },86461 .call_frame = .{ .alignment = .@"16" },
86632 .extra_temps = .{86462 .extra_temps = .{
86633 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfdf2" } } },86463 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfdf2" } },
86634 .unused,86464 .unused,
86635 .unused,86465 .unused,
86636 .unused,86466 .unused,
...@@ -86658,7 +86488,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86658,7 +86488,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86658 .extra_temps = .{86488 .extra_temps = .{
86659 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86489 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86660 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },86490 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
86661 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfdf2" } } },86491 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfdf2" } },
86662 .unused,86492 .unused,
86663 .unused,86493 .unused,
86664 .unused,86494 .unused,
...@@ -86689,7 +86519,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86689,7 +86519,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86689 .extra_temps = .{86519 .extra_temps = .{
86690 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86520 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86691 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },86521 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
86692 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfdf2" } } },86522 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfdf2" } },
86693 .unused,86523 .unused,
86694 .unused,86524 .unused,
86695 .unused,86525 .unused,
...@@ -86720,7 +86550,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86720,7 +86550,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86720 .extra_temps = .{86550 .extra_temps = .{
86721 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86551 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86722 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },86552 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
86723 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfdf2" } } },86553 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfdf2" } },
86724 .unused,86554 .unused,
86725 .unused,86555 .unused,
86726 .unused,86556 .unused,
...@@ -86749,7 +86579,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86749,7 +86579,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86749 },86579 },
86750 .call_frame = .{ .alignment = .@"16" },86580 .call_frame = .{ .alignment = .@"16" },
86751 .extra_temps = .{86581 .extra_temps = .{
86752 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfxf2" } } },86582 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfxf2" } },
86753 .unused,86583 .unused,
86754 .unused,86584 .unused,
86755 .unused,86585 .unused,
...@@ -86777,7 +86607,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86777,7 +86607,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86777 .extra_temps = .{86607 .extra_temps = .{
86778 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86608 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86779 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },86609 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
86780 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfxf2" } } },86610 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfxf2" } },
86781 .unused,86611 .unused,
86782 .unused,86612 .unused,
86783 .unused,86613 .unused,
...@@ -86809,7 +86639,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86809,7 +86639,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86809 .extra_temps = .{86639 .extra_temps = .{
86810 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86640 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86811 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },86641 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
86812 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfxf2" } } },86642 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfxf2" } },
86813 .unused,86643 .unused,
86814 .unused,86644 .unused,
86815 .unused,86645 .unused,
...@@ -86841,7 +86671,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86841,7 +86671,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86841 .extra_temps = .{86671 .extra_temps = .{
86842 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86672 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86843 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },86673 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
86844 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__trunctfxf2" } } },86674 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfxf2" } },
86845 .unused,86675 .unused,
86846 .unused,86676 .unused,
86847 .unused,86677 .unused,
...@@ -86921,7 +86751,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86921,7 +86751,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86921 },86751 },
86922 .call_frame = .{ .alignment = .@"16" },86752 .call_frame = .{ .alignment = .@"16" },
86923 .extra_temps = .{86753 .extra_temps = .{
86924 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhfsf2" } } },86754 .{ .type = .usize, .kind = .{ .extern_func = "__extendhfsf2" } },
86925 .unused,86755 .unused,
86926 .unused,86756 .unused,
86927 .unused,86757 .unused,
...@@ -86978,7 +86808,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -86978,7 +86808,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86978 .extra_temps = .{86808 .extra_temps = .{
86979 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86809 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
86980 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },86810 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
86981 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhfsf2" } } },86811 .{ .type = .usize, .kind = .{ .extern_func = "__extendhfsf2" } },
86982 .unused,86812 .unused,
86983 .unused,86813 .unused,
86984 .unused,86814 .unused,
...@@ -87010,7 +86840,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87010,7 +86840,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87010 .extra_temps = .{86840 .extra_temps = .{
87011 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },86841 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
87012 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },86842 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
87013 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhfsf2" } } },86843 .{ .type = .usize, .kind = .{ .extern_func = "__extendhfsf2" } },
87014 .unused,86844 .unused,
87015 .unused,86845 .unused,
87016 .unused,86846 .unused,
...@@ -87044,7 +86874,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87044,7 +86874,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87044 .{ .type = .f16, .kind = .{ .reg = .ax } },86874 .{ .type = .f16, .kind = .{ .reg = .ax } },
87045 .{ .type = .f32, .kind = .mem },86875 .{ .type = .f32, .kind = .mem },
87046 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },86876 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
87047 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhfsf2" } } },86877 .{ .type = .usize, .kind = .{ .extern_func = "__extendhfsf2" } },
87048 .unused,86878 .unused,
87049 .unused,86879 .unused,
87050 .unused,86880 .unused,
...@@ -87141,7 +86971,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87141,7 +86971,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87141 },86971 },
87142 .call_frame = .{ .alignment = .@"16" },86972 .call_frame = .{ .alignment = .@"16" },
87143 .extra_temps = .{86973 .extra_temps = .{
87144 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhfdf2" } } },86974 .{ .type = .usize, .kind = .{ .extern_func = "__extendhfdf2" } },
87145 .unused,86975 .unused,
87146 .unused,86976 .unused,
87147 .unused,86977 .unused,
...@@ -87202,7 +87032,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87202,7 +87032,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87202 .extra_temps = .{87032 .extra_temps = .{
87203 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },87033 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
87204 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },87034 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
87205 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhfdf2" } } },87035 .{ .type = .usize, .kind = .{ .extern_func = "__extendhfdf2" } },
87206 .unused,87036 .unused,
87207 .unused,87037 .unused,
87208 .unused,87038 .unused,
...@@ -87234,7 +87064,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87234,7 +87064,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87234 .extra_temps = .{87064 .extra_temps = .{
87235 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },87065 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
87236 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },87066 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
87237 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhfdf2" } } },87067 .{ .type = .usize, .kind = .{ .extern_func = "__extendhfdf2" } },
87238 .unused,87068 .unused,
87239 .unused,87069 .unused,
87240 .unused,87070 .unused,
...@@ -87268,7 +87098,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87268,7 +87098,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87268 .{ .type = .f16, .kind = .{ .reg = .ax } },87098 .{ .type = .f16, .kind = .{ .reg = .ax } },
87269 .{ .type = .f32, .kind = .mem },87099 .{ .type = .f32, .kind = .mem },
87270 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },87100 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
87271 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhfdf2" } } },87101 .{ .type = .usize, .kind = .{ .extern_func = "__extendhfdf2" } },
87272 .unused,87102 .unused,
87273 .unused,87103 .unused,
87274 .unused,87104 .unused,
...@@ -87324,7 +87154,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87324,7 +87154,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87324 },87154 },
87325 .call_frame = .{ .alignment = .@"16" },87155 .call_frame = .{ .alignment = .@"16" },
87326 .extra_temps = .{87156 .extra_temps = .{
87327 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhfxf2" } } },87157 .{ .type = .usize, .kind = .{ .extern_func = "__extendhfxf2" } },
87328 .unused,87158 .unused,
87329 .unused,87159 .unused,
87330 .unused,87160 .unused,
...@@ -87352,7 +87182,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87352,7 +87182,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87352 .extra_temps = .{87182 .extra_temps = .{
87353 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },87183 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
87354 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },87184 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
87355 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhfxf2" } } },87185 .{ .type = .usize, .kind = .{ .extern_func = "__extendhfxf2" } },
87356 .unused,87186 .unused,
87357 .unused,87187 .unused,
87358 .unused,87188 .unused,
...@@ -87385,7 +87215,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87385,7 +87215,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87385 .extra_temps = .{87215 .extra_temps = .{
87386 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },87216 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
87387 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },87217 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
87388 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhfxf2" } } },87218 .{ .type = .usize, .kind = .{ .extern_func = "__extendhfxf2" } },
87389 .unused,87219 .unused,
87390 .unused,87220 .unused,
87391 .unused,87221 .unused,
...@@ -87420,7 +87250,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87420,7 +87250,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87420 .{ .type = .f16, .kind = .{ .reg = .ax } },87250 .{ .type = .f16, .kind = .{ .reg = .ax } },
87421 .{ .type = .f32, .kind = .mem },87251 .{ .type = .f32, .kind = .mem },
87422 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },87252 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
87423 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhfxf2" } } },87253 .{ .type = .usize, .kind = .{ .extern_func = "__extendhfxf2" } },
87424 .unused,87254 .unused,
87425 .unused,87255 .unused,
87426 .unused,87256 .unused,
...@@ -87450,7 +87280,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87450,7 +87280,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87450 },87280 },
87451 .call_frame = .{ .alignment = .@"16" },87281 .call_frame = .{ .alignment = .@"16" },
87452 .extra_temps = .{87282 .extra_temps = .{
87453 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhftf2" } } },87283 .{ .type = .usize, .kind = .{ .extern_func = "__extendhftf2" } },
87454 .unused,87284 .unused,
87455 .unused,87285 .unused,
87456 .unused,87286 .unused,
...@@ -87478,7 +87308,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87478,7 +87308,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87478 .extra_temps = .{87308 .extra_temps = .{
87479 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },87309 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
87480 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },87310 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
87481 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhftf2" } } },87311 .{ .type = .usize, .kind = .{ .extern_func = "__extendhftf2" } },
87482 .unused,87312 .unused,
87483 .unused,87313 .unused,
87484 .unused,87314 .unused,
...@@ -87510,7 +87340,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87510,7 +87340,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87510 .extra_temps = .{87340 .extra_temps = .{
87511 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },87341 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
87512 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },87342 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
87513 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhftf2" } } },87343 .{ .type = .usize, .kind = .{ .extern_func = "__extendhftf2" } },
87514 .unused,87344 .unused,
87515 .unused,87345 .unused,
87516 .unused,87346 .unused,
...@@ -87544,7 +87374,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87544,7 +87374,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87544 .{ .type = .f16, .kind = .{ .reg = .ax } },87374 .{ .type = .f16, .kind = .{ .reg = .ax } },
87545 .{ .type = .f32, .kind = .mem },87375 .{ .type = .f32, .kind = .mem },
87546 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },87376 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
87547 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendhftf2" } } },87377 .{ .type = .usize, .kind = .{ .extern_func = "__extendhftf2" } },
87548 .unused,87378 .unused,
87549 .unused,87379 .unused,
87550 .unused,87380 .unused,
...@@ -87811,7 +87641,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87811,7 +87641,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87811 },87641 },
87812 .call_frame = .{ .alignment = .@"16" },87642 .call_frame = .{ .alignment = .@"16" },
87813 .extra_temps = .{87643 .extra_temps = .{
87814 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendsftf2" } } },87644 .{ .type = .usize, .kind = .{ .extern_func = "__extendsftf2" } },
87815 .unused,87645 .unused,
87816 .unused,87646 .unused,
87817 .unused,87647 .unused,
...@@ -87839,7 +87669,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87839,7 +87669,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87839 .extra_temps = .{87669 .extra_temps = .{
87840 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },87670 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
87841 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },87671 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
87842 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendsftf2" } } },87672 .{ .type = .usize, .kind = .{ .extern_func = "__extendsftf2" } },
87843 .unused,87673 .unused,
87844 .unused,87674 .unused,
87845 .unused,87675 .unused,
...@@ -87870,7 +87700,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87870,7 +87700,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87870 .extra_temps = .{87700 .extra_temps = .{
87871 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },87701 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
87872 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },87702 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
87873 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendsftf2" } } },87703 .{ .type = .usize, .kind = .{ .extern_func = "__extendsftf2" } },
87874 .unused,87704 .unused,
87875 .unused,87705 .unused,
87876 .unused,87706 .unused,
...@@ -87901,7 +87731,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87901,7 +87731,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87901 .extra_temps = .{87731 .extra_temps = .{
87902 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },87732 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
87903 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },87733 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
87904 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendsftf2" } } },87734 .{ .type = .usize, .kind = .{ .extern_func = "__extendsftf2" } },
87905 .unused,87735 .unused,
87906 .unused,87736 .unused,
87907 .unused,87737 .unused,
...@@ -87984,7 +87814,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -87984,7 +87814,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
87984 },87814 },
87985 .call_frame = .{ .alignment = .@"16" },87815 .call_frame = .{ .alignment = .@"16" },
87986 .extra_temps = .{87816 .extra_temps = .{
87987 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extenddftf2" } } },87817 .{ .type = .usize, .kind = .{ .extern_func = "__extenddftf2" } },
87988 .unused,87818 .unused,
87989 .unused,87819 .unused,
87990 .unused,87820 .unused,
...@@ -88012,7 +87842,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -88012,7 +87842,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
88012 .extra_temps = .{87842 .extra_temps = .{
88013 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },87843 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
88014 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },87844 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
88015 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extenddftf2" } } },87845 .{ .type = .usize, .kind = .{ .extern_func = "__extenddftf2" } },
88016 .unused,87846 .unused,
88017 .unused,87847 .unused,
88018 .unused,87848 .unused,
...@@ -88043,7 +87873,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -88043,7 +87873,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
88043 .extra_temps = .{87873 .extra_temps = .{
88044 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },87874 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
88045 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },87875 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
88046 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extenddftf2" } } },87876 .{ .type = .usize, .kind = .{ .extern_func = "__extenddftf2" } },
88047 .unused,87877 .unused,
88048 .unused,87878 .unused,
88049 .unused,87879 .unused,
...@@ -88074,7 +87904,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -88074,7 +87904,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
88074 .extra_temps = .{87904 .extra_temps = .{
88075 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },87905 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
88076 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },87906 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
88077 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extenddftf2" } } },87907 .{ .type = .usize, .kind = .{ .extern_func = "__extenddftf2" } },
88078 .unused,87908 .unused,
88079 .unused,87909 .unused,
88080 .unused,87910 .unused,
...@@ -88105,7 +87935,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -88105,7 +87935,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
88105 .call_frame = .{ .size = 16, .alignment = .@"16" },87935 .call_frame = .{ .size = 16, .alignment = .@"16" },
88106 .extra_temps = .{87936 .extra_temps = .{
88107 .{ .type = .f80, .kind = .{ .frame = .call_frame } },87937 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
88108 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendxftf2" } } },87938 .{ .type = .usize, .kind = .{ .extern_func = "__extendxftf2" } },
88109 .unused,87939 .unused,
88110 .unused,87940 .unused,
88111 .unused,87941 .unused,
...@@ -88133,7 +87963,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -88133,7 +87963,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
88133 .call_frame = .{ .size = 16, .alignment = .@"16" },87963 .call_frame = .{ .size = 16, .alignment = .@"16" },
88134 .extra_temps = .{87964 .extra_temps = .{
88135 .{ .type = .f80, .kind = .{ .frame = .call_frame } },87965 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
88136 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendxftf2" } } },87966 .{ .type = .usize, .kind = .{ .extern_func = "__extendxftf2" } },
88137 .unused,87967 .unused,
88138 .unused,87968 .unused,
88139 .unused,87969 .unused,
...@@ -88161,7 +87991,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -88161,7 +87991,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
88161 .call_frame = .{ .size = 16, .alignment = .@"16" },87991 .call_frame = .{ .size = 16, .alignment = .@"16" },
88162 .extra_temps = .{87992 .extra_temps = .{
88163 .{ .type = .f80, .kind = .{ .frame = .call_frame } },87993 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
88164 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendxftf2" } } },87994 .{ .type = .usize, .kind = .{ .extern_func = "__extendxftf2" } },
88165 .unused,87995 .unused,
88166 .unused,87996 .unused,
88167 .unused,87997 .unused,
...@@ -88191,7 +88021,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -88191,7 +88021,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
88191 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },88021 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
88192 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },88022 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
88193 .{ .type = .f80, .kind = .{ .frame = .call_frame } },88023 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
88194 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendxftf2" } } },88024 .{ .type = .usize, .kind = .{ .extern_func = "__extendxftf2" } },
88195 .unused,88025 .unused,
88196 .unused,88026 .unused,
88197 .unused,88027 .unused,
...@@ -88223,7 +88053,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -88223,7 +88053,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
88223 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },88053 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
88224 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },88054 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
88225 .{ .type = .f80, .kind = .{ .frame = .call_frame } },88055 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
88226 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendxftf2" } } },88056 .{ .type = .usize, .kind = .{ .extern_func = "__extendxftf2" } },
88227 .unused,88057 .unused,
88228 .unused,88058 .unused,
88229 .unused,88059 .unused,
...@@ -88255,7 +88085,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -88255,7 +88085,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
88255 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },88085 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
88256 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },88086 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
88257 .{ .type = .f80, .kind = .{ .frame = .call_frame } },88087 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
88258 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__extendxftf2" } } },88088 .{ .type = .usize, .kind = .{ .extern_func = "__extendxftf2" } },
88259 .unused,88089 .unused,
88260 .unused,88090 .unused,
88261 .unused,88091 .unused,
...@@ -99006,9 +98836,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99006,9 +98836,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99006 } }) catch |err| switch (err) {98836 } }) catch |err| switch (err) {
99007 error.SelectFailed => {98837 error.SelectFailed => {
99008 const elem_size = res_ty.abiSize(zcu);98838 const elem_size = res_ty.abiSize(zcu);
99009 const base = try cg.tempAllocReg(.usize, abi.RegisterClass.gp);98839 var base = try cg.tempAllocReg(.usize, abi.RegisterClass.gp);
99010 while (try ops[0].toBase(false, cg) or98840 while (try ops[0].toBase(false, cg) or
99011 try ops[1].toRegClass(true, .general_purpose, cg))98841 try ops[1].toRegClass(true, .general_purpose, cg) or
98842 try base.toRegClass(true, .general_purpose, cg))
99012 {}98843 {}
99013 const base_reg = base.tracking(cg).short.register.to64();98844 const base_reg = base.tracking(cg).short.register.to64();
99014 const rhs_reg = ops[1].tracking(cg).short.register.to64();98845 const rhs_reg = ops[1].tracking(cg).short.register.to64();
...@@ -99449,7 +99280,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99449,7 +99280,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99449 },99280 },
99450 .call_frame = .{ .alignment = .@"16" },99281 .call_frame = .{ .alignment = .@"16" },
99451 .extra_temps = .{99282 .extra_temps = .{
99452 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfsi" } } },99283 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfsi" } },
99453 .unused,99284 .unused,
99454 .unused,99285 .unused,
99455 .unused,99286 .unused,
...@@ -99475,7 +99306,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99475,7 +99306,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99475 },99306 },
99476 .call_frame = .{ .alignment = .@"16" },99307 .call_frame = .{ .alignment = .@"16" },
99477 .extra_temps = .{99308 .extra_temps = .{
99478 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfsi" } } },99309 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfsi" } },
99479 .unused,99310 .unused,
99480 .unused,99311 .unused,
99481 .unused,99312 .unused,
...@@ -99501,7 +99332,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99501,7 +99332,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99501 },99332 },
99502 .call_frame = .{ .alignment = .@"16" },99333 .call_frame = .{ .alignment = .@"16" },
99503 .extra_temps = .{99334 .extra_temps = .{
99504 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfdi" } } },99335 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfdi" } },
99505 .unused,99336 .unused,
99506 .unused,99337 .unused,
99507 .unused,99338 .unused,
...@@ -99527,7 +99358,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99527,7 +99358,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99527 },99358 },
99528 .call_frame = .{ .alignment = .@"16" },99359 .call_frame = .{ .alignment = .@"16" },
99529 .extra_temps = .{99360 .extra_temps = .{
99530 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfdi" } } },99361 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfdi" } },
99531 .unused,99362 .unused,
99532 .unused,99363 .unused,
99533 .unused,99364 .unused,
...@@ -99553,7 +99384,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99553,7 +99384,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99553 },99384 },
99554 .call_frame = .{ .alignment = .@"16" },99385 .call_frame = .{ .alignment = .@"16" },
99555 .extra_temps = .{99386 .extra_temps = .{
99556 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfti" } } },99387 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfti" } },
99557 .unused,99388 .unused,
99558 .unused,99389 .unused,
99559 .unused,99390 .unused,
...@@ -99579,7 +99410,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99579,7 +99410,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99579 },99410 },
99580 .call_frame = .{ .alignment = .@"16" },99411 .call_frame = .{ .alignment = .@"16" },
99581 .extra_temps = .{99412 .extra_temps = .{
99582 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfti" } } },99413 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfti" } },
99583 .unused,99414 .unused,
99584 .unused,99415 .unused,
99585 .unused,99416 .unused,
...@@ -99605,7 +99436,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99605,7 +99436,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99605 },99436 },
99606 .call_frame = .{ .alignment = .@"16" },99437 .call_frame = .{ .alignment = .@"16" },
99607 .extra_temps = .{99438 .extra_temps = .{
99608 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfdi" } } },99439 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfdi" } },
99609 .{ .type = .i64, .kind = .{ .reg = .rax } },99440 .{ .type = .i64, .kind = .{ .reg = .rax } },
99610 .{ .type = .usize, .kind = .{ .reg = .rdi } },99441 .{ .type = .usize, .kind = .{ .reg = .rdi } },
99611 .{ .type = .u32, .kind = .{ .reg = .ecx } },99442 .{ .type = .u32, .kind = .{ .reg = .ecx } },
...@@ -99636,7 +99467,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99636,7 +99467,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99636 },99467 },
99637 .call_frame = .{ .alignment = .@"16" },99468 .call_frame = .{ .alignment = .@"16" },
99638 .extra_temps = .{99469 .extra_temps = .{
99639 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfdi" } } },99470 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfdi" } },
99640 .{ .type = .i64, .kind = .{ .reg = .rax } },99471 .{ .type = .i64, .kind = .{ .reg = .rax } },
99641 .{ .type = .usize, .kind = .{ .reg = .rdi } },99472 .{ .type = .usize, .kind = .{ .reg = .rdi } },
99642 .{ .type = .u32, .kind = .{ .reg = .ecx } },99473 .{ .type = .u32, .kind = .{ .reg = .ecx } },
...@@ -99730,7 +99561,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99730,7 +99561,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99730 .extra_temps = .{99561 .extra_temps = .{
99731 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },99562 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
99732 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },99563 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
99733 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfsi" } } },99564 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfsi" } },
99734 .{ .type = .i32, .kind = .{ .reg = .eax } },99565 .{ .type = .i32, .kind = .{ .reg = .eax } },
99735 .unused,99566 .unused,
99736 .unused,99567 .unused,
...@@ -99762,7 +99593,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99762,7 +99593,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99762 .extra_temps = .{99593 .extra_temps = .{
99763 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },99594 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
99764 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },99595 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
99765 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfsi" } } },99596 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfsi" } },
99766 .{ .type = .i32, .kind = .{ .reg = .eax } },99597 .{ .type = .i32, .kind = .{ .reg = .eax } },
99767 .unused,99598 .unused,
99768 .unused,99599 .unused,
...@@ -99794,7 +99625,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99794,7 +99625,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99794 .extra_temps = .{99625 .extra_temps = .{
99795 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },99626 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
99796 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },99627 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
99797 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfsi" } } },99628 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfsi" } },
99798 .{ .type = .i32, .kind = .{ .reg = .eax } },99629 .{ .type = .i32, .kind = .{ .reg = .eax } },
99799 .unused,99630 .unused,
99800 .unused,99631 .unused,
...@@ -99826,7 +99657,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99826,7 +99657,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99826 .extra_temps = .{99657 .extra_temps = .{
99827 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },99658 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
99828 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },99659 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
99829 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfsi" } } },99660 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfsi" } },
99830 .{ .type = .i32, .kind = .{ .reg = .eax } },99661 .{ .type = .i32, .kind = .{ .reg = .eax } },
99831 .unused,99662 .unused,
99832 .unused,99663 .unused,
...@@ -99860,7 +99691,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99860,7 +99691,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99860 .{ .type = .i32, .kind = .{ .reg = .eax } },99691 .{ .type = .i32, .kind = .{ .reg = .eax } },
99861 .{ .type = .f32, .kind = .mem },99692 .{ .type = .f32, .kind = .mem },
99862 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },99693 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
99863 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfsi" } } },99694 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfsi" } },
99864 .unused,99695 .unused,
99865 .unused,99696 .unused,
99866 .unused,99697 .unused,
...@@ -99893,7 +99724,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -99893,7 +99724,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99893 .{ .type = .i32, .kind = .{ .reg = .eax } },99724 .{ .type = .i32, .kind = .{ .reg = .eax } },
99894 .{ .type = .f32, .kind = .mem },99725 .{ .type = .f32, .kind = .mem },
99895 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },99726 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
99896 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfsi" } } },99727 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfsi" } },
99897 .unused,99728 .unused,
99898 .unused,99729 .unused,
99899 .unused,99730 .unused,
...@@ -100014,7 +99845,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100014,7 +99845,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100014 .extra_temps = .{99845 .extra_temps = .{
100015 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },99846 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100016 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },99847 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100017 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfsi" } } },99848 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfsi" } },
100018 .{ .type = .i32, .kind = .{ .reg = .eax } },99849 .{ .type = .i32, .kind = .{ .reg = .eax } },
100019 .unused,99850 .unused,
100020 .unused,99851 .unused,
...@@ -100046,7 +99877,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100046,7 +99877,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100046 .extra_temps = .{99877 .extra_temps = .{
100047 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },99878 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100048 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },99879 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100049 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfsi" } } },99880 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfsi" } },
100050 .{ .type = .i32, .kind = .{ .reg = .eax } },99881 .{ .type = .i32, .kind = .{ .reg = .eax } },
100051 .unused,99882 .unused,
100052 .unused,99883 .unused,
...@@ -100080,7 +99911,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100080,7 +99911,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100080 .{ .type = .i32, .kind = .{ .reg = .eax } },99911 .{ .type = .i32, .kind = .{ .reg = .eax } },
100081 .{ .type = .f32, .kind = .mem },99912 .{ .type = .f32, .kind = .mem },
100082 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },99913 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100083 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfsi" } } },99914 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfsi" } },
100084 .unused,99915 .unused,
100085 .unused,99916 .unused,
100086 .unused,99917 .unused,
...@@ -100173,7 +100004,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100173,7 +100004,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100173 .extra_temps = .{100004 .extra_temps = .{
100174 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },100005 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100175 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100006 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100176 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfsi" } } },100007 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfsi" } },
100177 .{ .type = .i32, .kind = .{ .reg = .eax } },100008 .{ .type = .i32, .kind = .{ .reg = .eax } },
100178 .unused,100009 .unused,
100179 .unused,100010 .unused,
...@@ -100205,7 +100036,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100205,7 +100036,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100205 .extra_temps = .{100036 .extra_temps = .{
100206 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },100037 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100207 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100038 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100208 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfsi" } } },100039 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfsi" } },
100209 .{ .type = .u32, .kind = .{ .reg = .eax } },100040 .{ .type = .u32, .kind = .{ .reg = .eax } },
100210 .unused,100041 .unused,
100211 .unused,100042 .unused,
...@@ -100237,7 +100068,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100237,7 +100068,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100237 .extra_temps = .{100068 .extra_temps = .{
100238 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },100069 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100239 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100070 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100240 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfsi" } } },100071 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfsi" } },
100241 .{ .type = .i32, .kind = .{ .reg = .eax } },100072 .{ .type = .i32, .kind = .{ .reg = .eax } },
100242 .unused,100073 .unused,
100243 .unused,100074 .unused,
...@@ -100269,7 +100100,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100269,7 +100100,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100269 .extra_temps = .{100100 .extra_temps = .{
100270 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },100101 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100271 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100102 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100272 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfsi" } } },100103 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfsi" } },
100273 .{ .type = .u32, .kind = .{ .reg = .eax } },100104 .{ .type = .u32, .kind = .{ .reg = .eax } },
100274 .unused,100105 .unused,
100275 .unused,100106 .unused,
...@@ -100303,7 +100134,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100303,7 +100134,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100303 .{ .type = .i32, .kind = .{ .reg = .eax } },100134 .{ .type = .i32, .kind = .{ .reg = .eax } },
100304 .{ .type = .f32, .kind = .mem },100135 .{ .type = .f32, .kind = .mem },
100305 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100136 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100306 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfsi" } } },100137 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfsi" } },
100307 .unused,100138 .unused,
100308 .unused,100139 .unused,
100309 .unused,100140 .unused,
...@@ -100336,7 +100167,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100336,7 +100167,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100336 .{ .type = .u32, .kind = .{ .reg = .eax } },100167 .{ .type = .u32, .kind = .{ .reg = .eax } },
100337 .{ .type = .f32, .kind = .mem },100168 .{ .type = .f32, .kind = .mem },
100338 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100169 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100339 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfsi" } } },100170 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfsi" } },
100340 .unused,100171 .unused,
100341 .unused,100172 .unused,
100342 .unused,100173 .unused,
...@@ -100399,7 +100230,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100399,7 +100230,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100399 .extra_temps = .{100230 .extra_temps = .{
100400 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },100231 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100401 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100232 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100402 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfdi" } } },100233 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfdi" } },
100403 .{ .type = .i64, .kind = .{ .reg = .rax } },100234 .{ .type = .i64, .kind = .{ .reg = .rax } },
100404 .unused,100235 .unused,
100405 .unused,100236 .unused,
...@@ -100431,7 +100262,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100431,7 +100262,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100431 .extra_temps = .{100262 .extra_temps = .{
100432 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },100263 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100433 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100264 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100434 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfdi" } } },100265 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfdi" } },
100435 .{ .type = .u64, .kind = .{ .reg = .rax } },100266 .{ .type = .u64, .kind = .{ .reg = .rax } },
100436 .unused,100267 .unused,
100437 .unused,100268 .unused,
...@@ -100463,7 +100294,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100463,7 +100294,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100463 .extra_temps = .{100294 .extra_temps = .{
100464 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },100295 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100465 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100296 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100466 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfdi" } } },100297 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfdi" } },
100467 .{ .type = .i64, .kind = .{ .reg = .rax } },100298 .{ .type = .i64, .kind = .{ .reg = .rax } },
100468 .unused,100299 .unused,
100469 .unused,100300 .unused,
...@@ -100495,7 +100326,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100495,7 +100326,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100495 .extra_temps = .{100326 .extra_temps = .{
100496 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },100327 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100497 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100328 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100498 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfdi" } } },100329 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfdi" } },
100499 .{ .type = .u64, .kind = .{ .reg = .rax } },100330 .{ .type = .u64, .kind = .{ .reg = .rax } },
100500 .unused,100331 .unused,
100501 .unused,100332 .unused,
...@@ -100529,7 +100360,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100529,7 +100360,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100529 .{ .type = .i64, .kind = .{ .reg = .rax } },100360 .{ .type = .i64, .kind = .{ .reg = .rax } },
100530 .{ .type = .f32, .kind = .mem },100361 .{ .type = .f32, .kind = .mem },
100531 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100362 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100532 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfdi" } } },100363 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfdi" } },
100533 .unused,100364 .unused,
100534 .unused,100365 .unused,
100535 .unused,100366 .unused,
...@@ -100562,7 +100393,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100562,7 +100393,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100562 .{ .type = .u64, .kind = .{ .reg = .rax } },100393 .{ .type = .u64, .kind = .{ .reg = .rax } },
100563 .{ .type = .f32, .kind = .mem },100394 .{ .type = .f32, .kind = .mem },
100564 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100395 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100565 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfdi" } } },100396 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfdi" } },
100566 .unused,100397 .unused,
100567 .unused,100398 .unused,
100568 .unused,100399 .unused,
...@@ -100593,7 +100424,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100593,7 +100424,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100593 .extra_temps = .{100424 .extra_temps = .{
100594 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },100425 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100595 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100426 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100596 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfti" } } },100427 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfti" } },
100597 .{ .type = .u64, .kind = .{ .reg = .rax } },100428 .{ .type = .u64, .kind = .{ .reg = .rax } },
100598 .{ .type = .i64, .kind = .{ .reg = .rdx } },100429 .{ .type = .i64, .kind = .{ .reg = .rdx } },
100599 .unused,100430 .unused,
...@@ -100626,7 +100457,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100626,7 +100457,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100626 .extra_temps = .{100457 .extra_temps = .{
100627 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },100458 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100628 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100459 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100629 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfti" } } },100460 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfti" } },
100630 .{ .type = .u64, .kind = .{ .reg = .rax } },100461 .{ .type = .u64, .kind = .{ .reg = .rax } },
100631 .{ .type = .u64, .kind = .{ .reg = .rdx } },100462 .{ .type = .u64, .kind = .{ .reg = .rdx } },
100632 .unused,100463 .unused,
...@@ -100659,7 +100490,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100659,7 +100490,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100659 .extra_temps = .{100490 .extra_temps = .{
100660 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },100491 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100661 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100492 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100662 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfti" } } },100493 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfti" } },
100663 .{ .type = .u64, .kind = .{ .reg = .rax } },100494 .{ .type = .u64, .kind = .{ .reg = .rax } },
100664 .{ .type = .i64, .kind = .{ .reg = .rdx } },100495 .{ .type = .i64, .kind = .{ .reg = .rdx } },
100665 .unused,100496 .unused,
...@@ -100692,7 +100523,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100692,7 +100523,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100692 .extra_temps = .{100523 .extra_temps = .{
100693 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },100524 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
100694 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100525 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100695 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfti" } } },100526 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfti" } },
100696 .{ .type = .u64, .kind = .{ .reg = .rax } },100527 .{ .type = .u64, .kind = .{ .reg = .rax } },
100697 .{ .type = .u64, .kind = .{ .reg = .rdx } },100528 .{ .type = .u64, .kind = .{ .reg = .rdx } },
100698 .unused,100529 .unused,
...@@ -100727,7 +100558,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100727,7 +100558,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100727 .{ .type = .u64, .kind = .{ .reg = .rax } },100558 .{ .type = .u64, .kind = .{ .reg = .rax } },
100728 .{ .type = .f32, .kind = .mem },100559 .{ .type = .f32, .kind = .mem },
100729 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100560 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100730 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfti" } } },100561 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfti" } },
100731 .{ .type = .i64, .kind = .{ .reg = .rdx } },100562 .{ .type = .i64, .kind = .{ .reg = .rdx } },
100732 .unused,100563 .unused,
100733 .unused,100564 .unused,
...@@ -100761,7 +100592,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100761,7 +100592,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100761 .{ .type = .u64, .kind = .{ .reg = .rax } },100592 .{ .type = .u64, .kind = .{ .reg = .rax } },
100762 .{ .type = .f32, .kind = .mem },100593 .{ .type = .f32, .kind = .mem },
100763 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100594 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100764 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfti" } } },100595 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfti" } },
100765 .{ .type = .u64, .kind = .{ .reg = .rdx } },100596 .{ .type = .u64, .kind = .{ .reg = .rdx } },
100766 .unused,100597 .unused,
100767 .unused,100598 .unused,
...@@ -100796,7 +100627,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100796,7 +100627,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100796 .{ .type = .usize, .kind = .{ .reg = .rdi } },100627 .{ .type = .usize, .kind = .{ .reg = .rdi } },
100797 .{ .type = .usize, .kind = .{ .reg = .rsi } },100628 .{ .type = .usize, .kind = .{ .reg = .rsi } },
100798 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100629 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100799 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfei" } } },100630 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfei" } },
100800 .unused,100631 .unused,
100801 .unused,100632 .unused,
100802 .unused,100633 .unused,
...@@ -100831,7 +100662,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100831,7 +100662,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100831 .{ .type = .usize, .kind = .{ .reg = .rdi } },100662 .{ .type = .usize, .kind = .{ .reg = .rdi } },
100832 .{ .type = .usize, .kind = .{ .reg = .rsi } },100663 .{ .type = .usize, .kind = .{ .reg = .rsi } },
100833 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100664 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100834 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfei" } } },100665 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfei" } },
100835 .unused,100666 .unused,
100836 .unused,100667 .unused,
100837 .unused,100668 .unused,
...@@ -100866,7 +100697,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100866,7 +100697,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100866 .{ .type = .usize, .kind = .{ .reg = .rdi } },100697 .{ .type = .usize, .kind = .{ .reg = .rdi } },
100867 .{ .type = .usize, .kind = .{ .reg = .rsi } },100698 .{ .type = .usize, .kind = .{ .reg = .rsi } },
100868 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100699 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100869 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfei" } } },100700 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfei" } },
100870 .unused,100701 .unused,
100871 .unused,100702 .unused,
100872 .unused,100703 .unused,
...@@ -100901,7 +100732,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100901,7 +100732,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100901 .{ .type = .usize, .kind = .{ .reg = .rdi } },100732 .{ .type = .usize, .kind = .{ .reg = .rdi } },
100902 .{ .type = .usize, .kind = .{ .reg = .rsi } },100733 .{ .type = .usize, .kind = .{ .reg = .rsi } },
100903 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100734 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100904 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfei" } } },100735 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfei" } },
100905 .unused,100736 .unused,
100906 .unused,100737 .unused,
100907 .unused,100738 .unused,
...@@ -100937,7 +100768,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100937,7 +100768,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100937 .{ .type = .usize, .kind = .{ .reg = .rsi } },100768 .{ .type = .usize, .kind = .{ .reg = .rsi } },
100938 .{ .type = .f32, .kind = .mem },100769 .{ .type = .f32, .kind = .mem },
100939 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100770 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100940 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixhfei" } } },100771 .{ .type = .usize, .kind = .{ .extern_func = "__fixhfei" } },
100941 .unused,100772 .unused,
100942 .unused,100773 .unused,
100943 .unused,100774 .unused,
...@@ -100973,7 +100804,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -100973,7 +100804,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100973 .{ .type = .usize, .kind = .{ .reg = .rsi } },100804 .{ .type = .usize, .kind = .{ .reg = .rsi } },
100974 .{ .type = .f32, .kind = .mem },100805 .{ .type = .f32, .kind = .mem },
100975 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },100806 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
100976 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunshfei" } } },100807 .{ .type = .usize, .kind = .{ .extern_func = "__fixunshfei" } },
100977 .unused,100808 .unused,
100978 .unused,100809 .unused,
100979 .unused,100810 .unused,
...@@ -101115,7 +100946,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101115,7 +100946,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101115 },100946 },
101116 .call_frame = .{ .alignment = .@"16" },100947 .call_frame = .{ .alignment = .@"16" },
101117 .extra_temps = .{100948 .extra_temps = .{
101118 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfti" } } },100949 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfti" } },
101119 .unused,100950 .unused,
101120 .unused,100951 .unused,
101121 .unused,100952 .unused,
...@@ -101141,7 +100972,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101141,7 +100972,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101141 },100972 },
101142 .call_frame = .{ .alignment = .@"16" },100973 .call_frame = .{ .alignment = .@"16" },
101143 .extra_temps = .{100974 .extra_temps = .{
101144 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunssfti" } } },100975 .{ .type = .usize, .kind = .{ .extern_func = "__fixunssfti" } },
101145 .unused,100976 .unused,
101146 .unused,100977 .unused,
101147 .unused,100978 .unused,
...@@ -101170,7 +101001,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101170,7 +101001,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101170 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },101001 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
101171 .{ .type = .i64, .kind = .{ .reg = .rax } },101002 .{ .type = .i64, .kind = .{ .reg = .rax } },
101172 .{ .type = .vector_4_f32, .kind = .{ .smax_mem = .{} } },101003 .{ .type = .vector_4_f32, .kind = .{ .smax_mem = .{} } },
101173 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunssfti" } } },101004 .{ .type = .usize, .kind = .{ .extern_func = "__fixunssfti" } },
101174 .{ .type = .i64, .kind = .{ .reg = .rdx } },101005 .{ .type = .i64, .kind = .{ .reg = .rdx } },
101175 .{ .type = .usize, .kind = .{ .reg = .rdi } },101006 .{ .type = .usize, .kind = .{ .reg = .rdi } },
101176 .{ .type = .u32, .kind = .{ .reg = .ecx } },101007 .{ .type = .u32, .kind = .{ .reg = .ecx } },
...@@ -101211,7 +101042,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101211,7 +101042,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101211 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },101042 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
101212 .{ .type = .i64, .kind = .{ .reg = .rax } },101043 .{ .type = .i64, .kind = .{ .reg = .rax } },
101213 .{ .type = .vector_4_f32, .kind = .{ .smax_mem = .{} } },101044 .{ .type = .vector_4_f32, .kind = .{ .smax_mem = .{} } },
101214 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunssfti" } } },101045 .{ .type = .usize, .kind = .{ .extern_func = "__fixunssfti" } },
101215 .{ .type = .i64, .kind = .{ .reg = .rdx } },101046 .{ .type = .i64, .kind = .{ .reg = .rdx } },
101216 .{ .type = .usize, .kind = .{ .reg = .rdi } },101047 .{ .type = .usize, .kind = .{ .reg = .rdi } },
101217 .{ .type = .u32, .kind = .{ .reg = .ecx } },101048 .{ .type = .u32, .kind = .{ .reg = .ecx } },
...@@ -101252,7 +101083,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101252,7 +101083,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101252 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },101083 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
101253 .{ .type = .i64, .kind = .{ .reg = .rax } },101084 .{ .type = .i64, .kind = .{ .reg = .rax } },
101254 .{ .type = .vector_4_f32, .kind = .{ .smax_mem = .{} } },101085 .{ .type = .vector_4_f32, .kind = .{ .smax_mem = .{} } },
101255 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunssfti" } } },101086 .{ .type = .usize, .kind = .{ .extern_func = "__fixunssfti" } },
101256 .{ .type = .u32, .kind = .{ .reg = .ecx } },101087 .{ .type = .u32, .kind = .{ .reg = .ecx } },
101257 .{ .type = .i64, .kind = .{ .reg = .rdx } },101088 .{ .type = .i64, .kind = .{ .reg = .rdx } },
101258 .{ .type = .usize, .kind = .{ .reg = .rdi } },101089 .{ .type = .usize, .kind = .{ .reg = .rdi } },
...@@ -101290,7 +101121,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101290,7 +101121,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101290 },101121 },
101291 .call_frame = .{ .alignment = .@"16" },101122 .call_frame = .{ .alignment = .@"16" },
101292 .extra_temps = .{101123 .extra_temps = .{
101293 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunssfti" } } },101124 .{ .type = .usize, .kind = .{ .extern_func = "__fixunssfti" } },
101294 .{ .type = .i64, .kind = .{ .reg = .rax } },101125 .{ .type = .i64, .kind = .{ .reg = .rax } },
101295 .{ .type = .i64, .kind = .{ .reg = .rdx } },101126 .{ .type = .i64, .kind = .{ .reg = .rdx } },
101296 .{ .type = .usize, .kind = .{ .reg = .rdi } },101127 .{ .type = .usize, .kind = .{ .reg = .rdi } },
...@@ -101500,7 +101331,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101500,7 +101331,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101500 .extra_temps = .{101331 .extra_temps = .{
101501 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },101332 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
101502 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },101333 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
101503 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfsi" } } },101334 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfsi" } },
101504 .{ .type = .i32, .kind = .{ .reg = .eax } },101335 .{ .type = .i32, .kind = .{ .reg = .eax } },
101505 .unused,101336 .unused,
101506 .unused,101337 .unused,
...@@ -101531,7 +101362,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101531,7 +101362,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101531 .extra_temps = .{101362 .extra_temps = .{
101532 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },101363 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
101533 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },101364 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
101534 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfsi" } } },101365 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfsi" } },
101535 .{ .type = .i32, .kind = .{ .reg = .eax } },101366 .{ .type = .i32, .kind = .{ .reg = .eax } },
101536 .unused,101367 .unused,
101537 .unused,101368 .unused,
...@@ -101562,7 +101393,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101562,7 +101393,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101562 .extra_temps = .{101393 .extra_temps = .{
101563 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },101394 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
101564 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },101395 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
101565 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfsi" } } },101396 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfsi" } },
101566 .{ .type = .i32, .kind = .{ .reg = .eax } },101397 .{ .type = .i32, .kind = .{ .reg = .eax } },
101567 .unused,101398 .unused,
101568 .unused,101399 .unused,
...@@ -101593,7 +101424,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101593,7 +101424,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101593 .extra_temps = .{101424 .extra_temps = .{
101594 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },101425 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
101595 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },101426 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
101596 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfsi" } } },101427 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfsi" } },
101597 .{ .type = .i32, .kind = .{ .reg = .eax } },101428 .{ .type = .i32, .kind = .{ .reg = .eax } },
101598 .unused,101429 .unused,
101599 .unused,101430 .unused,
...@@ -101796,7 +101627,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101796,7 +101627,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101796 .extra_temps = .{101627 .extra_temps = .{
101797 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },101628 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
101798 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },101629 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
101799 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfsi" } } },101630 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfsi" } },
101800 .{ .type = .i32, .kind = .{ .reg = .eax } },101631 .{ .type = .i32, .kind = .{ .reg = .eax } },
101801 .unused,101632 .unused,
101802 .unused,101633 .unused,
...@@ -101827,7 +101658,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101827,7 +101658,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101827 .extra_temps = .{101658 .extra_temps = .{
101828 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },101659 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
101829 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },101660 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
101830 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfsi" } } },101661 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfsi" } },
101831 .{ .type = .i32, .kind = .{ .reg = .eax } },101662 .{ .type = .i32, .kind = .{ .reg = .eax } },
101832 .unused,101663 .unused,
101833 .unused,101664 .unused,
...@@ -101940,7 +101771,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101940,7 +101771,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101940 .extra_temps = .{101771 .extra_temps = .{
101941 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },101772 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
101942 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },101773 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
101943 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfsi" } } },101774 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfsi" } },
101944 .{ .type = .i32, .kind = .{ .reg = .eax } },101775 .{ .type = .i32, .kind = .{ .reg = .eax } },
101945 .unused,101776 .unused,
101946 .unused,101777 .unused,
...@@ -101971,7 +101802,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -101971,7 +101802,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
101971 .extra_temps = .{101802 .extra_temps = .{
101972 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },101803 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
101973 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },101804 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
101974 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunssfsi" } } },101805 .{ .type = .usize, .kind = .{ .extern_func = "__fixunssfsi" } },
101975 .{ .type = .u32, .kind = .{ .reg = .eax } },101806 .{ .type = .u32, .kind = .{ .reg = .eax } },
101976 .unused,101807 .unused,
101977 .unused,101808 .unused,
...@@ -102002,7 +101833,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102002,7 +101833,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102002 .extra_temps = .{101833 .extra_temps = .{
102003 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },101834 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
102004 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },101835 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102005 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfsi" } } },101836 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfsi" } },
102006 .{ .type = .i32, .kind = .{ .reg = .eax } },101837 .{ .type = .i32, .kind = .{ .reg = .eax } },
102007 .unused,101838 .unused,
102008 .unused,101839 .unused,
...@@ -102033,7 +101864,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102033,7 +101864,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102033 .extra_temps = .{101864 .extra_temps = .{
102034 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },101865 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
102035 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },101866 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102036 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunssfsi" } } },101867 .{ .type = .usize, .kind = .{ .extern_func = "__fixunssfsi" } },
102037 .{ .type = .u32, .kind = .{ .reg = .eax } },101868 .{ .type = .u32, .kind = .{ .reg = .eax } },
102038 .unused,101869 .unused,
102039 .unused,101870 .unused,
...@@ -102122,7 +101953,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102122,7 +101953,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102122 .extra_temps = .{101953 .extra_temps = .{
102123 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },101954 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
102124 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },101955 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102125 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfdi" } } },101956 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfdi" } },
102126 .{ .type = .i64, .kind = .{ .reg = .rax } },101957 .{ .type = .i64, .kind = .{ .reg = .rax } },
102127 .unused,101958 .unused,
102128 .unused,101959 .unused,
...@@ -102153,7 +101984,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102153,7 +101984,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102153 .extra_temps = .{101984 .extra_temps = .{
102154 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },101985 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
102155 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },101986 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102156 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunssfdi" } } },101987 .{ .type = .usize, .kind = .{ .extern_func = "__fixunssfdi" } },
102157 .{ .type = .u64, .kind = .{ .reg = .rax } },101988 .{ .type = .u64, .kind = .{ .reg = .rax } },
102158 .unused,101989 .unused,
102159 .unused,101990 .unused,
...@@ -102184,7 +102015,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102184,7 +102015,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102184 .extra_temps = .{102015 .extra_temps = .{
102185 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },102016 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
102186 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },102017 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102187 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfdi" } } },102018 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfdi" } },
102188 .{ .type = .i64, .kind = .{ .reg = .rax } },102019 .{ .type = .i64, .kind = .{ .reg = .rax } },
102189 .unused,102020 .unused,
102190 .unused,102021 .unused,
...@@ -102215,7 +102046,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102215,7 +102046,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102215 .extra_temps = .{102046 .extra_temps = .{
102216 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },102047 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
102217 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },102048 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102218 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunssfdi" } } },102049 .{ .type = .usize, .kind = .{ .extern_func = "__fixunssfdi" } },
102219 .{ .type = .u64, .kind = .{ .reg = .rax } },102050 .{ .type = .u64, .kind = .{ .reg = .rax } },
102220 .unused,102051 .unused,
102221 .unused,102052 .unused,
...@@ -102246,7 +102077,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102246,7 +102077,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102246 .extra_temps = .{102077 .extra_temps = .{
102247 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },102078 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
102248 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },102079 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102249 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfti" } } },102080 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfti" } },
102250 .{ .type = .u64, .kind = .{ .reg = .rax } },102081 .{ .type = .u64, .kind = .{ .reg = .rax } },
102251 .{ .type = .i64, .kind = .{ .reg = .rdx } },102082 .{ .type = .i64, .kind = .{ .reg = .rdx } },
102252 .unused,102083 .unused,
...@@ -102278,7 +102109,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102278,7 +102109,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102278 .extra_temps = .{102109 .extra_temps = .{
102279 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },102110 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
102280 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },102111 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102281 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunssfti" } } },102112 .{ .type = .usize, .kind = .{ .extern_func = "__fixunssfti" } },
102282 .{ .type = .u64, .kind = .{ .reg = .rax } },102113 .{ .type = .u64, .kind = .{ .reg = .rax } },
102283 .{ .type = .u64, .kind = .{ .reg = .rdx } },102114 .{ .type = .u64, .kind = .{ .reg = .rdx } },
102284 .unused,102115 .unused,
...@@ -102310,7 +102141,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102310,7 +102141,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102310 .extra_temps = .{102141 .extra_temps = .{
102311 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },102142 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
102312 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },102143 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102313 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfti" } } },102144 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfti" } },
102314 .{ .type = .u64, .kind = .{ .reg = .rax } },102145 .{ .type = .u64, .kind = .{ .reg = .rax } },
102315 .{ .type = .i64, .kind = .{ .reg = .rdx } },102146 .{ .type = .i64, .kind = .{ .reg = .rdx } },
102316 .unused,102147 .unused,
...@@ -102342,7 +102173,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102342,7 +102173,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102342 .extra_temps = .{102173 .extra_temps = .{
102343 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },102174 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
102344 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },102175 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102345 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunssfti" } } },102176 .{ .type = .usize, .kind = .{ .extern_func = "__fixunssfti" } },
102346 .{ .type = .u64, .kind = .{ .reg = .rax } },102177 .{ .type = .u64, .kind = .{ .reg = .rax } },
102347 .{ .type = .u64, .kind = .{ .reg = .rdx } },102178 .{ .type = .u64, .kind = .{ .reg = .rdx } },
102348 .unused,102179 .unused,
...@@ -102377,7 +102208,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102377,7 +102208,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102377 .{ .type = .usize, .kind = .{ .reg = .rdi } },102208 .{ .type = .usize, .kind = .{ .reg = .rdi } },
102378 .{ .type = .usize, .kind = .{ .reg = .rsi } },102209 .{ .type = .usize, .kind = .{ .reg = .rsi } },
102379 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },102210 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102380 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfei" } } },102211 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfei" } },
102381 .unused,102212 .unused,
102382 .unused,102213 .unused,
102383 .unused,102214 .unused,
...@@ -102411,7 +102242,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102411,7 +102242,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102411 .{ .type = .usize, .kind = .{ .reg = .rdi } },102242 .{ .type = .usize, .kind = .{ .reg = .rdi } },
102412 .{ .type = .usize, .kind = .{ .reg = .rsi } },102243 .{ .type = .usize, .kind = .{ .reg = .rsi } },
102413 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },102244 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102414 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunssfei" } } },102245 .{ .type = .usize, .kind = .{ .extern_func = "__fixunssfei" } },
102415 .unused,102246 .unused,
102416 .unused,102247 .unused,
102417 .unused,102248 .unused,
...@@ -102445,7 +102276,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102445,7 +102276,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102445 .{ .type = .usize, .kind = .{ .reg = .rdi } },102276 .{ .type = .usize, .kind = .{ .reg = .rdi } },
102446 .{ .type = .usize, .kind = .{ .reg = .rsi } },102277 .{ .type = .usize, .kind = .{ .reg = .rsi } },
102447 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },102278 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102448 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfei" } } },102279 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfei" } },
102449 .unused,102280 .unused,
102450 .unused,102281 .unused,
102451 .unused,102282 .unused,
...@@ -102479,7 +102310,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102479,7 +102310,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102479 .{ .type = .usize, .kind = .{ .reg = .rdi } },102310 .{ .type = .usize, .kind = .{ .reg = .rdi } },
102480 .{ .type = .usize, .kind = .{ .reg = .rsi } },102311 .{ .type = .usize, .kind = .{ .reg = .rsi } },
102481 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },102312 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
102482 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunssfei" } } },102313 .{ .type = .usize, .kind = .{ .extern_func = "__fixunssfei" } },
102483 .unused,102314 .unused,
102484 .unused,102315 .unused,
102485 .unused,102316 .unused,
...@@ -102818,7 +102649,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102818,7 +102649,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102818 },102649 },
102819 .call_frame = .{ .alignment = .@"16" },102650 .call_frame = .{ .alignment = .@"16" },
102820 .extra_temps = .{102651 .extra_temps = .{
102821 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfti" } } },102652 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfti" } },
102822 .unused,102653 .unused,
102823 .unused,102654 .unused,
102824 .unused,102655 .unused,
...@@ -102844,7 +102675,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102844,7 +102675,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102844 },102675 },
102845 .call_frame = .{ .alignment = .@"16" },102676 .call_frame = .{ .alignment = .@"16" },
102846 .extra_temps = .{102677 .extra_temps = .{
102847 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfti" } } },102678 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfti" } },
102848 .unused,102679 .unused,
102849 .unused,102680 .unused,
102850 .unused,102681 .unused,
...@@ -102872,7 +102703,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102872,7 +102703,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102872 .extra_temps = .{102703 .extra_temps = .{
102873 .{ .type = .usize, .kind = .{ .reg = .rdi } },102704 .{ .type = .usize, .kind = .{ .reg = .rdi } },
102874 .{ .type = .usize, .kind = .{ .reg = .rsi } },102705 .{ .type = .usize, .kind = .{ .reg = .rsi } },
102875 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfei" } } },102706 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfei" } },
102876 .unused,102707 .unused,
102877 .unused,102708 .unused,
102878 .unused,102709 .unused,
...@@ -102900,7 +102731,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -102900,7 +102731,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
102900 .extra_temps = .{102731 .extra_temps = .{
102901 .{ .type = .usize, .kind = .{ .reg = .rdi } },102732 .{ .type = .usize, .kind = .{ .reg = .rdi } },
102902 .{ .type = .usize, .kind = .{ .reg = .rsi } },102733 .{ .type = .usize, .kind = .{ .reg = .rsi } },
102903 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfei" } } },102734 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfei" } },
102904 .unused,102735 .unused,
102905 .unused,102736 .unused,
102906 .unused,102737 .unused,
...@@ -103205,7 +103036,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103205,7 +103036,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103205 .extra_temps = .{103036 .extra_temps = .{
103206 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103037 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
103207 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103038 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
103208 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfsi" } } },103039 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfsi" } },
103209 .{ .type = .i32, .kind = .{ .reg = .eax } },103040 .{ .type = .i32, .kind = .{ .reg = .eax } },
103210 .unused,103041 .unused,
103211 .unused,103042 .unused,
...@@ -103236,7 +103067,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103236,7 +103067,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103236 .extra_temps = .{103067 .extra_temps = .{
103237 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103068 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
103238 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103069 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
103239 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfsi" } } },103070 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfsi" } },
103240 .{ .type = .i32, .kind = .{ .reg = .eax } },103071 .{ .type = .i32, .kind = .{ .reg = .eax } },
103241 .unused,103072 .unused,
103242 .unused,103073 .unused,
...@@ -103267,7 +103098,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103267,7 +103098,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103267 .extra_temps = .{103098 .extra_temps = .{
103268 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103099 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
103269 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103100 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
103270 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfsi" } } },103101 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfsi" } },
103271 .{ .type = .i32, .kind = .{ .reg = .eax } },103102 .{ .type = .i32, .kind = .{ .reg = .eax } },
103272 .unused,103103 .unused,
103273 .unused,103104 .unused,
...@@ -103298,7 +103129,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103298,7 +103129,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103298 .extra_temps = .{103129 .extra_temps = .{
103299 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103130 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
103300 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103131 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
103301 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfsi" } } },103132 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfsi" } },
103302 .{ .type = .i32, .kind = .{ .reg = .eax } },103133 .{ .type = .i32, .kind = .{ .reg = .eax } },
103303 .unused,103134 .unused,
103304 .unused,103135 .unused,
...@@ -103329,7 +103160,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103329,7 +103160,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103329 .extra_temps = .{103160 .extra_temps = .{
103330 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103161 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
103331 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103162 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
103332 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfsi" } } },103163 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfsi" } },
103333 .{ .type = .i32, .kind = .{ .reg = .eax } },103164 .{ .type = .i32, .kind = .{ .reg = .eax } },
103334 .unused,103165 .unused,
103335 .unused,103166 .unused,
...@@ -103361,7 +103192,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103361,7 +103192,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103361 .extra_temps = .{103192 .extra_temps = .{
103362 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103193 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
103363 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103194 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
103364 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixsfsi" } } },103195 .{ .type = .usize, .kind = .{ .extern_func = "__fixsfsi" } },
103365 .{ .type = .i32, .kind = .{ .reg = .eax } },103196 .{ .type = .i32, .kind = .{ .reg = .eax } },
103366 .unused,103197 .unused,
103367 .unused,103198 .unused,
...@@ -103692,7 +103523,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103692,7 +103523,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103692 .extra_temps = .{103523 .extra_temps = .{
103693 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103524 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
103694 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103525 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
103695 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfsi" } } },103526 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfsi" } },
103696 .{ .type = .i32, .kind = .{ .reg = .eax } },103527 .{ .type = .i32, .kind = .{ .reg = .eax } },
103697 .unused,103528 .unused,
103698 .unused,103529 .unused,
...@@ -103723,7 +103554,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103723,7 +103554,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103723 .extra_temps = .{103554 .extra_temps = .{
103724 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103555 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
103725 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103556 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
103726 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfsi" } } },103557 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfsi" } },
103727 .{ .type = .i32, .kind = .{ .reg = .eax } },103558 .{ .type = .i32, .kind = .{ .reg = .eax } },
103728 .unused,103559 .unused,
103729 .unused,103560 .unused,
...@@ -103754,7 +103585,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103754,7 +103585,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103754 .extra_temps = .{103585 .extra_temps = .{
103755 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103586 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
103756 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103587 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
103757 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfsi" } } },103588 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfsi" } },
103758 .{ .type = .i32, .kind = .{ .reg = .eax } },103589 .{ .type = .i32, .kind = .{ .reg = .eax } },
103759 .unused,103590 .unused,
103760 .unused,103591 .unused,
...@@ -103952,7 +103783,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103952,7 +103783,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103952 .extra_temps = .{103783 .extra_temps = .{
103953 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103784 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
103954 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103785 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
103955 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfsi" } } },103786 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfsi" } },
103956 .{ .type = .i32, .kind = .{ .reg = .eax } },103787 .{ .type = .i32, .kind = .{ .reg = .eax } },
103957 .unused,103788 .unused,
103958 .unused,103789 .unused,
...@@ -103983,7 +103814,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103983,7 +103814,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103983 .extra_temps = .{103814 .extra_temps = .{
103984 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103815 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
103985 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103816 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
103986 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfsi" } } },103817 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfsi" } },
103987 .{ .type = .u32, .kind = .{ .reg = .eax } },103818 .{ .type = .u32, .kind = .{ .reg = .eax } },
103988 .unused,103819 .unused,
103989 .unused,103820 .unused,
...@@ -104014,7 +103845,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104014,7 +103845,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104014 .extra_temps = .{103845 .extra_temps = .{
104015 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103846 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104016 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103847 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104017 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfsi" } } },103848 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfsi" } },
104018 .{ .type = .i32, .kind = .{ .reg = .eax } },103849 .{ .type = .i32, .kind = .{ .reg = .eax } },
104019 .unused,103850 .unused,
104020 .unused,103851 .unused,
...@@ -104045,7 +103876,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104045,7 +103876,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104045 .extra_temps = .{103876 .extra_temps = .{
104046 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103877 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104047 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103878 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104048 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfsi" } } },103879 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfsi" } },
104049 .{ .type = .u32, .kind = .{ .reg = .eax } },103880 .{ .type = .u32, .kind = .{ .reg = .eax } },
104050 .unused,103881 .unused,
104051 .unused,103882 .unused,
...@@ -104076,7 +103907,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104076,7 +103907,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104076 .extra_temps = .{103907 .extra_temps = .{
104077 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103908 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104078 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103909 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104079 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfsi" } } },103910 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfsi" } },
104080 .{ .type = .i32, .kind = .{ .reg = .eax } },103911 .{ .type = .i32, .kind = .{ .reg = .eax } },
104081 .unused,103912 .unused,
104082 .unused,103913 .unused,
...@@ -104108,7 +103939,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104108,7 +103939,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104108 .extra_temps = .{103939 .extra_temps = .{
104109 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },103940 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104110 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },103941 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104111 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfsi" } } },103942 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfsi" } },
104112 .{ .type = .u32, .kind = .{ .reg = .eax } },103943 .{ .type = .u32, .kind = .{ .reg = .eax } },
104113 .unused,103944 .unused,
104114 .unused,103945 .unused,
...@@ -104233,7 +104064,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104233,7 +104064,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104233 .extra_temps = .{104064 .extra_temps = .{
104234 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },104065 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104235 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104066 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104236 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfdi" } } },104067 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfdi" } },
104237 .{ .type = .i64, .kind = .{ .reg = .rax } },104068 .{ .type = .i64, .kind = .{ .reg = .rax } },
104238 .unused,104069 .unused,
104239 .unused,104070 .unused,
...@@ -104264,7 +104095,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104264,7 +104095,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104264 .extra_temps = .{104095 .extra_temps = .{
104265 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },104096 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104266 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104097 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104267 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfdi" } } },104098 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfdi" } },
104268 .{ .type = .u64, .kind = .{ .reg = .rax } },104099 .{ .type = .u64, .kind = .{ .reg = .rax } },
104269 .unused,104100 .unused,
104270 .unused,104101 .unused,
...@@ -104295,7 +104126,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104295,7 +104126,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104295 .extra_temps = .{104126 .extra_temps = .{
104296 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },104127 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104297 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104128 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104298 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfdi" } } },104129 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfdi" } },
104299 .{ .type = .i64, .kind = .{ .reg = .rax } },104130 .{ .type = .i64, .kind = .{ .reg = .rax } },
104300 .unused,104131 .unused,
104301 .unused,104132 .unused,
...@@ -104326,7 +104157,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104326,7 +104157,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104326 .extra_temps = .{104157 .extra_temps = .{
104327 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },104158 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104328 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104159 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104329 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfdi" } } },104160 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfdi" } },
104330 .{ .type = .u64, .kind = .{ .reg = .rax } },104161 .{ .type = .u64, .kind = .{ .reg = .rax } },
104331 .unused,104162 .unused,
104332 .unused,104163 .unused,
...@@ -104357,7 +104188,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104357,7 +104188,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104357 .extra_temps = .{104188 .extra_temps = .{
104358 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },104189 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104359 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104190 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104360 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfdi" } } },104191 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfdi" } },
104361 .{ .type = .i64, .kind = .{ .reg = .rax } },104192 .{ .type = .i64, .kind = .{ .reg = .rax } },
104362 .unused,104193 .unused,
104363 .unused,104194 .unused,
...@@ -104389,7 +104220,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104389,7 +104220,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104389 .extra_temps = .{104220 .extra_temps = .{
104390 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },104221 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104391 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104222 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104392 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfdi" } } },104223 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfdi" } },
104393 .{ .type = .u64, .kind = .{ .reg = .rax } },104224 .{ .type = .u64, .kind = .{ .reg = .rax } },
104394 .unused,104225 .unused,
104395 .unused,104226 .unused,
...@@ -104421,7 +104252,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104421,7 +104252,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104421 .extra_temps = .{104252 .extra_temps = .{
104422 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },104253 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104423 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104254 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104424 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfti" } } },104255 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfti" } },
104425 .{ .type = .u64, .kind = .{ .reg = .rax } },104256 .{ .type = .u64, .kind = .{ .reg = .rax } },
104426 .{ .type = .i64, .kind = .{ .reg = .rdx } },104257 .{ .type = .i64, .kind = .{ .reg = .rdx } },
104427 .unused,104258 .unused,
...@@ -104453,7 +104284,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104453,7 +104284,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104453 .extra_temps = .{104284 .extra_temps = .{
104454 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },104285 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104455 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104286 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104456 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfti" } } },104287 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfti" } },
104457 .{ .type = .u64, .kind = .{ .reg = .rax } },104288 .{ .type = .u64, .kind = .{ .reg = .rax } },
104458 .{ .type = .u64, .kind = .{ .reg = .rdx } },104289 .{ .type = .u64, .kind = .{ .reg = .rdx } },
104459 .unused,104290 .unused,
...@@ -104485,7 +104316,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104485,7 +104316,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104485 .extra_temps = .{104316 .extra_temps = .{
104486 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },104317 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104487 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104318 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104488 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfti" } } },104319 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfti" } },
104489 .{ .type = .u64, .kind = .{ .reg = .rax } },104320 .{ .type = .u64, .kind = .{ .reg = .rax } },
104490 .{ .type = .i64, .kind = .{ .reg = .rdx } },104321 .{ .type = .i64, .kind = .{ .reg = .rdx } },
104491 .unused,104322 .unused,
...@@ -104517,7 +104348,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104517,7 +104348,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104517 .extra_temps = .{104348 .extra_temps = .{
104518 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },104349 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104519 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104350 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104520 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfti" } } },104351 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfti" } },
104521 .{ .type = .u64, .kind = .{ .reg = .rax } },104352 .{ .type = .u64, .kind = .{ .reg = .rax } },
104522 .{ .type = .u64, .kind = .{ .reg = .rdx } },104353 .{ .type = .u64, .kind = .{ .reg = .rdx } },
104523 .unused,104354 .unused,
...@@ -104549,7 +104380,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104549,7 +104380,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104549 .extra_temps = .{104380 .extra_temps = .{
104550 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },104381 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104551 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104382 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104552 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfti" } } },104383 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfti" } },
104553 .{ .type = .u64, .kind = .{ .reg = .rax } },104384 .{ .type = .u64, .kind = .{ .reg = .rax } },
104554 .{ .type = .i64, .kind = .{ .reg = .rdx } },104385 .{ .type = .i64, .kind = .{ .reg = .rdx } },
104555 .unused,104386 .unused,
...@@ -104582,7 +104413,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104582,7 +104413,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104582 .extra_temps = .{104413 .extra_temps = .{
104583 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },104414 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
104584 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104415 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104585 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfti" } } },104416 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfti" } },
104586 .{ .type = .u64, .kind = .{ .reg = .rax } },104417 .{ .type = .u64, .kind = .{ .reg = .rax } },
104587 .{ .type = .u64, .kind = .{ .reg = .rdx } },104418 .{ .type = .u64, .kind = .{ .reg = .rdx } },
104588 .unused,104419 .unused,
...@@ -104618,7 +104449,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104618,7 +104449,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104618 .{ .type = .usize, .kind = .{ .reg = .rdi } },104449 .{ .type = .usize, .kind = .{ .reg = .rdi } },
104619 .{ .type = .usize, .kind = .{ .reg = .rsi } },104450 .{ .type = .usize, .kind = .{ .reg = .rsi } },
104620 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104451 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104621 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfei" } } },104452 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfei" } },
104622 .unused,104453 .unused,
104623 .unused,104454 .unused,
104624 .unused,104455 .unused,
...@@ -104652,7 +104483,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104652,7 +104483,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104652 .{ .type = .usize, .kind = .{ .reg = .rdi } },104483 .{ .type = .usize, .kind = .{ .reg = .rdi } },
104653 .{ .type = .usize, .kind = .{ .reg = .rsi } },104484 .{ .type = .usize, .kind = .{ .reg = .rsi } },
104654 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104485 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104655 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfei" } } },104486 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfei" } },
104656 .unused,104487 .unused,
104657 .unused,104488 .unused,
104658 .unused,104489 .unused,
...@@ -104686,7 +104517,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104686,7 +104517,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104686 .{ .type = .usize, .kind = .{ .reg = .rdi } },104517 .{ .type = .usize, .kind = .{ .reg = .rdi } },
104687 .{ .type = .usize, .kind = .{ .reg = .rsi } },104518 .{ .type = .usize, .kind = .{ .reg = .rsi } },
104688 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104519 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104689 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfei" } } },104520 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfei" } },
104690 .unused,104521 .unused,
104691 .unused,104522 .unused,
104692 .unused,104523 .unused,
...@@ -104720,7 +104551,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104720,7 +104551,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104720 .{ .type = .usize, .kind = .{ .reg = .rdi } },104551 .{ .type = .usize, .kind = .{ .reg = .rdi } },
104721 .{ .type = .usize, .kind = .{ .reg = .rsi } },104552 .{ .type = .usize, .kind = .{ .reg = .rsi } },
104722 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104553 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104723 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfei" } } },104554 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfei" } },
104724 .unused,104555 .unused,
104725 .unused,104556 .unused,
104726 .unused,104557 .unused,
...@@ -104754,7 +104585,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104754,7 +104585,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104754 .{ .type = .usize, .kind = .{ .reg = .rdi } },104585 .{ .type = .usize, .kind = .{ .reg = .rdi } },
104755 .{ .type = .usize, .kind = .{ .reg = .rsi } },104586 .{ .type = .usize, .kind = .{ .reg = .rsi } },
104756 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104587 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104757 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixdfei" } } },104588 .{ .type = .usize, .kind = .{ .extern_func = "__fixdfei" } },
104758 .unused,104589 .unused,
104759 .unused,104590 .unused,
104760 .unused,104591 .unused,
...@@ -104789,7 +104620,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -104789,7 +104620,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104789 .{ .type = .usize, .kind = .{ .reg = .rdi } },104620 .{ .type = .usize, .kind = .{ .reg = .rdi } },
104790 .{ .type = .usize, .kind = .{ .reg = .rsi } },104621 .{ .type = .usize, .kind = .{ .reg = .rsi } },
104791 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },104622 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
104792 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsdfei" } } },104623 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsdfei" } },
104793 .unused,104624 .unused,
104794 .unused,104625 .unused,
104795 .unused,104626 .unused,
...@@ -105810,7 +105641,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -105810,7 +105641,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
105810 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },105641 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
105811 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },105642 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
105812 .{ .type = .f80, .kind = .{ .frame = .call_frame } },105643 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
105813 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfti" } } },105644 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfti" } },
105814 .{ .type = .u64, .kind = .{ .reg = .rax } },105645 .{ .type = .u64, .kind = .{ .reg = .rax } },
105815 .unused,105646 .unused,
105816 .unused,105647 .unused,
...@@ -105842,7 +105673,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -105842,7 +105673,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
105842 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },105673 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
105843 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },105674 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
105844 .{ .type = .f80, .kind = .{ .frame = .call_frame } },105675 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
105845 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfti" } } },105676 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfti" } },
105846 .{ .type = .u64, .kind = .{ .reg = .rax } },105677 .{ .type = .u64, .kind = .{ .reg = .rax } },
105847 .unused,105678 .unused,
105848 .unused,105679 .unused,
...@@ -105874,7 +105705,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -105874,7 +105705,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
105874 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },105705 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
105875 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },105706 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
105876 .{ .type = .f80, .kind = .{ .frame = .call_frame } },105707 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
105877 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfti" } } },105708 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfti" } },
105878 .{ .type = .u64, .kind = .{ .reg = .rax } },105709 .{ .type = .u64, .kind = .{ .reg = .rax } },
105879 .unused,105710 .unused,
105880 .unused,105711 .unused,
...@@ -105905,7 +105736,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -105905,7 +105736,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
105905 .extra_temps = .{105736 .extra_temps = .{
105906 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },105737 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
105907 .{ .type = .f80, .kind = .{ .frame = .call_frame } },105738 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
105908 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixxfti" } } },105739 .{ .type = .usize, .kind = .{ .extern_func = "__fixxfti" } },
105909 .unused,105740 .unused,
105910 .unused,105741 .unused,
105911 .unused,105742 .unused,
...@@ -105933,7 +105764,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -105933,7 +105764,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
105933 .extra_temps = .{105764 .extra_temps = .{
105934 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },105765 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
105935 .{ .type = .f80, .kind = .{ .frame = .call_frame } },105766 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
105936 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfti" } } },105767 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfti" } },
105937 .unused,105768 .unused,
105938 .unused,105769 .unused,
105939 .unused,105770 .unused,
...@@ -105961,7 +105792,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -105961,7 +105792,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
105961 .extra_temps = .{105792 .extra_temps = .{
105962 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },105793 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
105963 .{ .type = .f80, .kind = .{ .frame = .call_frame } },105794 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
105964 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixxfti" } } },105795 .{ .type = .usize, .kind = .{ .extern_func = "__fixxfti" } },
105965 .unused,105796 .unused,
105966 .unused,105797 .unused,
105967 .unused,105798 .unused,
...@@ -105989,7 +105820,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -105989,7 +105820,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
105989 .extra_temps = .{105820 .extra_temps = .{
105990 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },105821 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
105991 .{ .type = .f80, .kind = .{ .frame = .call_frame } },105822 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
105992 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfti" } } },105823 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfti" } },
105993 .unused,105824 .unused,
105994 .unused,105825 .unused,
105995 .unused,105826 .unused,
...@@ -106017,7 +105848,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106017,7 +105848,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106017 .extra_temps = .{105848 .extra_temps = .{
106018 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },105849 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106019 .{ .type = .f80, .kind = .{ .frame = .call_frame } },105850 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106020 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixxfti" } } },105851 .{ .type = .usize, .kind = .{ .extern_func = "__fixxfti" } },
106021 .unused,105852 .unused,
106022 .unused,105853 .unused,
106023 .unused,105854 .unused,
...@@ -106045,7 +105876,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106045,7 +105876,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106045 .extra_temps = .{105876 .extra_temps = .{
106046 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },105877 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106047 .{ .type = .f80, .kind = .{ .frame = .call_frame } },105878 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106048 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfti" } } },105879 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfti" } },
106049 .unused,105880 .unused,
106050 .unused,105881 .unused,
106051 .unused,105882 .unused,
...@@ -106074,7 +105905,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106074,7 +105905,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106074 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },105905 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106075 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },105906 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106076 .{ .type = .f80, .kind = .{ .frame = .call_frame } },105907 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106077 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixxfti" } } },105908 .{ .type = .usize, .kind = .{ .extern_func = "__fixxfti" } },
106078 .{ .type = .u64, .kind = .{ .reg = .rax } },105909 .{ .type = .u64, .kind = .{ .reg = .rax } },
106079 .{ .type = .i64, .kind = .{ .reg = .rdx } },105910 .{ .type = .i64, .kind = .{ .reg = .rdx } },
106080 .unused,105911 .unused,
...@@ -106107,7 +105938,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106107,7 +105938,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106107 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },105938 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106108 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },105939 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106109 .{ .type = .f80, .kind = .{ .frame = .call_frame } },105940 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106110 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfti" } } },105941 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfti" } },
106111 .{ .type = .u64, .kind = .{ .reg = .rax } },105942 .{ .type = .u64, .kind = .{ .reg = .rax } },
106112 .{ .type = .u64, .kind = .{ .reg = .rdx } },105943 .{ .type = .u64, .kind = .{ .reg = .rdx } },
106113 .unused,105944 .unused,
...@@ -106140,7 +105971,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106140,7 +105971,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106140 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },105971 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106141 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },105972 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106142 .{ .type = .f80, .kind = .{ .frame = .call_frame } },105973 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106143 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixxfti" } } },105974 .{ .type = .usize, .kind = .{ .extern_func = "__fixxfti" } },
106144 .{ .type = .u64, .kind = .{ .reg = .rax } },105975 .{ .type = .u64, .kind = .{ .reg = .rax } },
106145 .{ .type = .i64, .kind = .{ .reg = .rdx } },105976 .{ .type = .i64, .kind = .{ .reg = .rdx } },
106146 .unused,105977 .unused,
...@@ -106173,7 +106004,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106173,7 +106004,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106173 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106004 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106174 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106005 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106175 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106006 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106176 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfti" } } },106007 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfti" } },
106177 .{ .type = .u64, .kind = .{ .reg = .rax } },106008 .{ .type = .u64, .kind = .{ .reg = .rax } },
106178 .{ .type = .u64, .kind = .{ .reg = .rdx } },106009 .{ .type = .u64, .kind = .{ .reg = .rdx } },
106179 .unused,106010 .unused,
...@@ -106206,7 +106037,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106206,7 +106037,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106206 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106037 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106207 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106038 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106208 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106039 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106209 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixxfti" } } },106040 .{ .type = .usize, .kind = .{ .extern_func = "__fixxfti" } },
106210 .{ .type = .u64, .kind = .{ .reg = .rax } },106041 .{ .type = .u64, .kind = .{ .reg = .rax } },
106211 .{ .type = .i64, .kind = .{ .reg = .rdx } },106042 .{ .type = .i64, .kind = .{ .reg = .rdx } },
106212 .unused,106043 .unused,
...@@ -106239,7 +106070,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106239,7 +106070,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106239 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106070 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106240 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106071 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106241 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106072 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106242 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfti" } } },106073 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfti" } },
106243 .{ .type = .u64, .kind = .{ .reg = .rax } },106074 .{ .type = .u64, .kind = .{ .reg = .rax } },
106244 .{ .type = .u64, .kind = .{ .reg = .rdx } },106075 .{ .type = .u64, .kind = .{ .reg = .rdx } },
106245 .unused,106076 .unused,
...@@ -106273,7 +106104,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106273,7 +106104,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106273 .{ .type = .usize, .kind = .{ .reg = .rsi } },106104 .{ .type = .usize, .kind = .{ .reg = .rsi } },
106274 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106105 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106275 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106106 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106276 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixxfei" } } },106107 .{ .type = .usize, .kind = .{ .extern_func = "__fixxfei" } },
106277 .unused,106108 .unused,
106278 .unused,106109 .unused,
106279 .unused,106110 .unused,
...@@ -106303,7 +106134,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106303,7 +106134,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106303 .{ .type = .usize, .kind = .{ .reg = .rsi } },106134 .{ .type = .usize, .kind = .{ .reg = .rsi } },
106304 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106135 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106305 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106136 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106306 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfei" } } },106137 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfei" } },
106307 .unused,106138 .unused,
106308 .unused,106139 .unused,
106309 .unused,106140 .unused,
...@@ -106333,7 +106164,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106333,7 +106164,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106333 .{ .type = .usize, .kind = .{ .reg = .rsi } },106164 .{ .type = .usize, .kind = .{ .reg = .rsi } },
106334 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106165 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106335 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106166 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106336 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixxfei" } } },106167 .{ .type = .usize, .kind = .{ .extern_func = "__fixxfei" } },
106337 .unused,106168 .unused,
106338 .unused,106169 .unused,
106339 .unused,106170 .unused,
...@@ -106363,7 +106194,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106363,7 +106194,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106363 .{ .type = .usize, .kind = .{ .reg = .rsi } },106194 .{ .type = .usize, .kind = .{ .reg = .rsi } },
106364 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106195 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106365 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106196 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106366 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfei" } } },106197 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfei" } },
106367 .unused,106198 .unused,
106368 .unused,106199 .unused,
106369 .unused,106200 .unused,
...@@ -106393,7 +106224,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106393,7 +106224,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106393 .{ .type = .usize, .kind = .{ .reg = .rsi } },106224 .{ .type = .usize, .kind = .{ .reg = .rsi } },
106394 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106225 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106395 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106226 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106396 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixxfei" } } },106227 .{ .type = .usize, .kind = .{ .extern_func = "__fixxfei" } },
106397 .unused,106228 .unused,
106398 .unused,106229 .unused,
106399 .unused,106230 .unused,
...@@ -106423,7 +106254,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106423,7 +106254,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106423 .{ .type = .usize, .kind = .{ .reg = .rsi } },106254 .{ .type = .usize, .kind = .{ .reg = .rsi } },
106424 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106255 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106425 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106256 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106426 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfei" } } },106257 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfei" } },
106427 .unused,106258 .unused,
106428 .unused,106259 .unused,
106429 .unused,106260 .unused,
...@@ -106455,7 +106286,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106455,7 +106286,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106455 .{ .type = .usize, .kind = .{ .reg = .rsi } },106286 .{ .type = .usize, .kind = .{ .reg = .rsi } },
106456 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106287 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106457 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106288 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106458 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixxfei" } } },106289 .{ .type = .usize, .kind = .{ .extern_func = "__fixxfei" } },
106459 .unused,106290 .unused,
106460 .unused,106291 .unused,
106461 .unused,106292 .unused,
...@@ -106490,7 +106321,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106490,7 +106321,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106490 .{ .type = .usize, .kind = .{ .reg = .rsi } },106321 .{ .type = .usize, .kind = .{ .reg = .rsi } },
106491 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106322 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106492 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106323 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106493 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfei" } } },106324 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfei" } },
106494 .unused,106325 .unused,
106495 .unused,106326 .unused,
106496 .unused,106327 .unused,
...@@ -106525,7 +106356,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106525,7 +106356,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106525 .{ .type = .usize, .kind = .{ .reg = .rsi } },106356 .{ .type = .usize, .kind = .{ .reg = .rsi } },
106526 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106357 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106527 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106358 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106528 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixxfei" } } },106359 .{ .type = .usize, .kind = .{ .extern_func = "__fixxfei" } },
106529 .unused,106360 .unused,
106530 .unused,106361 .unused,
106531 .unused,106362 .unused,
...@@ -106560,7 +106391,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106560,7 +106391,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106560 .{ .type = .usize, .kind = .{ .reg = .rsi } },106391 .{ .type = .usize, .kind = .{ .reg = .rsi } },
106561 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106392 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106562 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106393 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106563 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfei" } } },106394 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfei" } },
106564 .unused,106395 .unused,
106565 .unused,106396 .unused,
106566 .unused,106397 .unused,
...@@ -106595,7 +106426,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106595,7 +106426,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106595 .{ .type = .usize, .kind = .{ .reg = .rsi } },106426 .{ .type = .usize, .kind = .{ .reg = .rsi } },
106596 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106427 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106597 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106428 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106598 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixxfei" } } },106429 .{ .type = .usize, .kind = .{ .extern_func = "__fixxfei" } },
106599 .unused,106430 .unused,
106600 .unused,106431 .unused,
106601 .unused,106432 .unused,
...@@ -106630,7 +106461,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106630,7 +106461,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106630 .{ .type = .usize, .kind = .{ .reg = .rsi } },106461 .{ .type = .usize, .kind = .{ .reg = .rsi } },
106631 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },106462 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
106632 .{ .type = .f80, .kind = .{ .frame = .call_frame } },106463 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
106633 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunsxfei" } } },106464 .{ .type = .usize, .kind = .{ .extern_func = "__fixunsxfei" } },
106634 .unused,106465 .unused,
106635 .unused,106466 .unused,
106636 .unused,106467 .unused,
...@@ -106662,7 +106493,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106662,7 +106493,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106662 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },106493 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
106663 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106494 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106664 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106495 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
106665 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfsi" } } },106496 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
106666 .{ .type = .i32, .kind = .{ .reg = .eax } },106497 .{ .type = .i32, .kind = .{ .reg = .eax } },
106667 .unused,106498 .unused,
106668 .unused,106499 .unused,
...@@ -106695,7 +106526,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106695,7 +106526,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106695 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },106526 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
106696 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106527 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106697 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106528 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
106698 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfsi" } } },106529 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
106699 .{ .type = .i32, .kind = .{ .reg = .eax } },106530 .{ .type = .i32, .kind = .{ .reg = .eax } },
106700 .unused,106531 .unused,
106701 .unused,106532 .unused,
...@@ -106728,7 +106559,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106728,7 +106559,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106728 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },106559 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
106729 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106560 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106730 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106561 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
106731 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfsi" } } },106562 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
106732 .{ .type = .i32, .kind = .{ .reg = .eax } },106563 .{ .type = .i32, .kind = .{ .reg = .eax } },
106733 .unused,106564 .unused,
106734 .unused,106565 .unused,
...@@ -106761,7 +106592,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106761,7 +106592,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106761 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },106592 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
106762 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106593 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106763 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106594 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
106764 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfsi" } } },106595 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
106765 .{ .type = .i32, .kind = .{ .reg = .eax } },106596 .{ .type = .i32, .kind = .{ .reg = .eax } },
106766 .unused,106597 .unused,
106767 .unused,106598 .unused,
...@@ -106794,7 +106625,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106794,7 +106625,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106794 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },106625 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
106795 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106626 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106796 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106627 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
106797 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfsi" } } },106628 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
106798 .{ .type = .i32, .kind = .{ .reg = .eax } },106629 .{ .type = .i32, .kind = .{ .reg = .eax } },
106799 .unused,106630 .unused,
106800 .unused,106631 .unused,
...@@ -106827,7 +106658,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106827,7 +106658,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106827 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },106658 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
106828 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106659 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106829 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106660 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
106830 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfsi" } } },106661 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
106831 .{ .type = .i32, .kind = .{ .reg = .eax } },106662 .{ .type = .i32, .kind = .{ .reg = .eax } },
106832 .unused,106663 .unused,
106833 .unused,106664 .unused,
...@@ -106859,7 +106690,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106859,7 +106690,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106859 .extra_temps = .{106690 .extra_temps = .{
106860 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106691 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106861 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106692 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
106862 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfsi" } } },106693 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
106863 .{ .type = .i32, .kind = .{ .reg = .eax } },106694 .{ .type = .i32, .kind = .{ .reg = .eax } },
106864 .unused,106695 .unused,
106865 .unused,106696 .unused,
...@@ -106890,7 +106721,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106890,7 +106721,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106890 .extra_temps = .{106721 .extra_temps = .{
106891 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106722 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106892 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106723 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
106893 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfsi" } } },106724 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
106894 .{ .type = .i32, .kind = .{ .reg = .eax } },106725 .{ .type = .i32, .kind = .{ .reg = .eax } },
106895 .unused,106726 .unused,
106896 .unused,106727 .unused,
...@@ -106921,7 +106752,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106921,7 +106752,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106921 .extra_temps = .{106752 .extra_temps = .{
106922 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106753 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
106923 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106754 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
106924 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfsi" } } },106755 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
106925 .{ .type = .i32, .kind = .{ .reg = .eax } },106756 .{ .type = .i32, .kind = .{ .reg = .eax } },
106926 .unused,106757 .unused,
106927 .unused,106758 .unused,
...@@ -106950,7 +106781,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106950,7 +106781,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106950 },106781 },
106951 .call_frame = .{ .alignment = .@"16" },106782 .call_frame = .{ .alignment = .@"16" },
106952 .extra_temps = .{106783 .extra_temps = .{
106953 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfsi" } } },106784 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
106954 .unused,106785 .unused,
106955 .unused,106786 .unused,
106956 .unused,106787 .unused,
...@@ -106976,7 +106807,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -106976,7 +106807,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
106976 },106807 },
106977 .call_frame = .{ .alignment = .@"16" },106808 .call_frame = .{ .alignment = .@"16" },
106978 .extra_temps = .{106809 .extra_temps = .{
106979 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfsi" } } },106810 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfsi" } },
106980 .unused,106811 .unused,
106981 .unused,106812 .unused,
106982 .unused,106813 .unused,
...@@ -107004,7 +106835,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107004,7 +106835,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107004 .extra_temps = .{106835 .extra_temps = .{
107005 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106836 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107006 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106837 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107007 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfsi" } } },106838 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
107008 .{ .type = .i32, .kind = .{ .reg = .eax } },106839 .{ .type = .i32, .kind = .{ .reg = .eax } },
107009 .unused,106840 .unused,
107010 .unused,106841 .unused,
...@@ -107035,7 +106866,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107035,7 +106866,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107035 .extra_temps = .{106866 .extra_temps = .{
107036 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106867 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107037 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106868 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107038 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfsi" } } },106869 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfsi" } },
107039 .{ .type = .u32, .kind = .{ .reg = .eax } },106870 .{ .type = .u32, .kind = .{ .reg = .eax } },
107040 .unused,106871 .unused,
107041 .unused,106872 .unused,
...@@ -107066,7 +106897,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107066,7 +106897,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107066 .extra_temps = .{106897 .extra_temps = .{
107067 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106898 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107068 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106899 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107069 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfsi" } } },106900 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
107070 .{ .type = .i32, .kind = .{ .reg = .eax } },106901 .{ .type = .i32, .kind = .{ .reg = .eax } },
107071 .unused,106902 .unused,
107072 .unused,106903 .unused,
...@@ -107097,7 +106928,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107097,7 +106928,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107097 .extra_temps = .{106928 .extra_temps = .{
107098 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106929 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107099 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106930 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107100 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfsi" } } },106931 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfsi" } },
107101 .{ .type = .u32, .kind = .{ .reg = .eax } },106932 .{ .type = .u32, .kind = .{ .reg = .eax } },
107102 .unused,106933 .unused,
107103 .unused,106934 .unused,
...@@ -107128,7 +106959,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107128,7 +106959,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107128 .extra_temps = .{106959 .extra_temps = .{
107129 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106960 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107130 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106961 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107131 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfsi" } } },106962 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
107132 .{ .type = .i32, .kind = .{ .reg = .eax } },106963 .{ .type = .i32, .kind = .{ .reg = .eax } },
107133 .unused,106964 .unused,
107134 .unused,106965 .unused,
...@@ -107159,7 +106990,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107159,7 +106990,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107159 .extra_temps = .{106990 .extra_temps = .{
107160 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },106991 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107161 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },106992 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107162 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfsi" } } },106993 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfsi" } },
107163 .{ .type = .u32, .kind = .{ .reg = .eax } },106994 .{ .type = .u32, .kind = .{ .reg = .eax } },
107164 .unused,106995 .unused,
107165 .unused,106996 .unused,
...@@ -107188,7 +107019,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107188,7 +107019,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107188 },107019 },
107189 .call_frame = .{ .alignment = .@"16" },107020 .call_frame = .{ .alignment = .@"16" },
107190 .extra_temps = .{107021 .extra_temps = .{
107191 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfdi" } } },107022 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfdi" } },
107192 .unused,107023 .unused,
107193 .unused,107024 .unused,
107194 .unused,107025 .unused,
...@@ -107214,7 +107045,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107214,7 +107045,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107214 },107045 },
107215 .call_frame = .{ .alignment = .@"16" },107046 .call_frame = .{ .alignment = .@"16" },
107216 .extra_temps = .{107047 .extra_temps = .{
107217 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfdi" } } },107048 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfdi" } },
107218 .unused,107049 .unused,
107219 .unused,107050 .unused,
107220 .unused,107051 .unused,
...@@ -107242,7 +107073,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107242,7 +107073,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107242 .extra_temps = .{107073 .extra_temps = .{
107243 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },107074 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107244 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107075 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107245 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfdi" } } },107076 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfdi" } },
107246 .{ .type = .i64, .kind = .{ .reg = .rax } },107077 .{ .type = .i64, .kind = .{ .reg = .rax } },
107247 .unused,107078 .unused,
107248 .unused,107079 .unused,
...@@ -107273,7 +107104,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107273,7 +107104,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107273 .extra_temps = .{107104 .extra_temps = .{
107274 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },107105 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107275 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107106 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107276 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfdi" } } },107107 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfdi" } },
107277 .{ .type = .u64, .kind = .{ .reg = .rax } },107108 .{ .type = .u64, .kind = .{ .reg = .rax } },
107278 .unused,107109 .unused,
107279 .unused,107110 .unused,
...@@ -107304,7 +107135,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107304,7 +107135,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107304 .extra_temps = .{107135 .extra_temps = .{
107305 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },107136 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107306 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107137 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107307 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfdi" } } },107138 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfdi" } },
107308 .{ .type = .i64, .kind = .{ .reg = .rax } },107139 .{ .type = .i64, .kind = .{ .reg = .rax } },
107309 .unused,107140 .unused,
107310 .unused,107141 .unused,
...@@ -107335,7 +107166,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107335,7 +107166,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107335 .extra_temps = .{107166 .extra_temps = .{
107336 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },107167 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107337 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107168 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107338 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfdi" } } },107169 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfdi" } },
107339 .{ .type = .u64, .kind = .{ .reg = .rax } },107170 .{ .type = .u64, .kind = .{ .reg = .rax } },
107340 .unused,107171 .unused,
107341 .unused,107172 .unused,
...@@ -107366,7 +107197,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107366,7 +107197,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107366 .extra_temps = .{107197 .extra_temps = .{
107367 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },107198 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107368 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107199 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107369 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfdi" } } },107200 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfdi" } },
107370 .{ .type = .i64, .kind = .{ .reg = .rax } },107201 .{ .type = .i64, .kind = .{ .reg = .rax } },
107371 .unused,107202 .unused,
107372 .unused,107203 .unused,
...@@ -107397,7 +107228,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107397,7 +107228,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107397 .extra_temps = .{107228 .extra_temps = .{
107398 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },107229 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107399 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107230 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107400 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfdi" } } },107231 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfdi" } },
107401 .{ .type = .u64, .kind = .{ .reg = .rax } },107232 .{ .type = .u64, .kind = .{ .reg = .rax } },
107402 .unused,107233 .unused,
107403 .unused,107234 .unused,
...@@ -107426,7 +107257,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107426,7 +107257,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107426 },107257 },
107427 .call_frame = .{ .alignment = .@"16" },107258 .call_frame = .{ .alignment = .@"16" },
107428 .extra_temps = .{107259 .extra_temps = .{
107429 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfti" } } },107260 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfti" } },
107430 .unused,107261 .unused,
107431 .unused,107262 .unused,
107432 .unused,107263 .unused,
...@@ -107452,7 +107283,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107452,7 +107283,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107452 },107283 },
107453 .call_frame = .{ .alignment = .@"16" },107284 .call_frame = .{ .alignment = .@"16" },
107454 .extra_temps = .{107285 .extra_temps = .{
107455 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfti" } } },107286 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
107456 .unused,107287 .unused,
107457 .unused,107288 .unused,
107458 .unused,107289 .unused,
...@@ -107480,7 +107311,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107480,7 +107311,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107480 .extra_temps = .{107311 .extra_temps = .{
107481 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },107312 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107482 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107313 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107483 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfti" } } },107314 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfti" } },
107484 .{ .type = .u64, .kind = .{ .reg = .rax } },107315 .{ .type = .u64, .kind = .{ .reg = .rax } },
107485 .{ .type = .i64, .kind = .{ .reg = .rdx } },107316 .{ .type = .i64, .kind = .{ .reg = .rdx } },
107486 .unused,107317 .unused,
...@@ -107512,7 +107343,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107512,7 +107343,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107512 .extra_temps = .{107343 .extra_temps = .{
107513 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },107344 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107514 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107345 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107515 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfti" } } },107346 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
107516 .{ .type = .u64, .kind = .{ .reg = .rax } },107347 .{ .type = .u64, .kind = .{ .reg = .rax } },
107517 .{ .type = .u64, .kind = .{ .reg = .rdx } },107348 .{ .type = .u64, .kind = .{ .reg = .rdx } },
107518 .unused,107349 .unused,
...@@ -107544,7 +107375,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107544,7 +107375,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107544 .extra_temps = .{107375 .extra_temps = .{
107545 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },107376 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107546 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107377 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107547 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfti" } } },107378 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfti" } },
107548 .{ .type = .u64, .kind = .{ .reg = .rax } },107379 .{ .type = .u64, .kind = .{ .reg = .rax } },
107549 .{ .type = .i64, .kind = .{ .reg = .rdx } },107380 .{ .type = .i64, .kind = .{ .reg = .rdx } },
107550 .unused,107381 .unused,
...@@ -107576,7 +107407,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107576,7 +107407,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107576 .extra_temps = .{107407 .extra_temps = .{
107577 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },107408 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107578 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107409 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107579 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfti" } } },107410 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
107580 .{ .type = .u64, .kind = .{ .reg = .rax } },107411 .{ .type = .u64, .kind = .{ .reg = .rax } },
107581 .{ .type = .u64, .kind = .{ .reg = .rdx } },107412 .{ .type = .u64, .kind = .{ .reg = .rdx } },
107582 .unused,107413 .unused,
...@@ -107608,7 +107439,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107608,7 +107439,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107608 .extra_temps = .{107439 .extra_temps = .{
107609 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },107440 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107610 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107441 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107611 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfti" } } },107442 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfti" } },
107612 .{ .type = .u64, .kind = .{ .reg = .rax } },107443 .{ .type = .u64, .kind = .{ .reg = .rax } },
107613 .{ .type = .i64, .kind = .{ .reg = .rdx } },107444 .{ .type = .i64, .kind = .{ .reg = .rdx } },
107614 .unused,107445 .unused,
...@@ -107640,7 +107471,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107640,7 +107471,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107640 .extra_temps = .{107471 .extra_temps = .{
107641 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },107472 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
107642 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107473 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107643 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfti" } } },107474 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
107644 .{ .type = .u64, .kind = .{ .reg = .rax } },107475 .{ .type = .u64, .kind = .{ .reg = .rax } },
107645 .{ .type = .u64, .kind = .{ .reg = .rdx } },107476 .{ .type = .u64, .kind = .{ .reg = .rdx } },
107646 .unused,107477 .unused,
...@@ -107672,7 +107503,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107672,7 +107503,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107672 .extra_temps = .{107503 .extra_temps = .{
107673 .{ .type = .usize, .kind = .{ .reg = .rdi } },107504 .{ .type = .usize, .kind = .{ .reg = .rdi } },
107674 .{ .type = .usize, .kind = .{ .reg = .rsi } },107505 .{ .type = .usize, .kind = .{ .reg = .rsi } },
107675 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfei" } } },107506 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfei" } },
107676 .unused,107507 .unused,
107677 .unused,107508 .unused,
107678 .unused,107509 .unused,
...@@ -107700,7 +107531,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107700,7 +107531,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107700 .extra_temps = .{107531 .extra_temps = .{
107701 .{ .type = .usize, .kind = .{ .reg = .rdi } },107532 .{ .type = .usize, .kind = .{ .reg = .rdi } },
107702 .{ .type = .usize, .kind = .{ .reg = .rsi } },107533 .{ .type = .usize, .kind = .{ .reg = .rsi } },
107703 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfei" } } },107534 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfei" } },
107704 .unused,107535 .unused,
107705 .unused,107536 .unused,
107706 .unused,107537 .unused,
...@@ -107731,7 +107562,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107731,7 +107562,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107731 .{ .type = .usize, .kind = .{ .reg = .rdi } },107562 .{ .type = .usize, .kind = .{ .reg = .rdi } },
107732 .{ .type = .usize, .kind = .{ .reg = .rsi } },107563 .{ .type = .usize, .kind = .{ .reg = .rsi } },
107733 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107564 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107734 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfei" } } },107565 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfei" } },
107735 .unused,107566 .unused,
107736 .unused,107567 .unused,
107737 .unused,107568 .unused,
...@@ -107765,7 +107596,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107765,7 +107596,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107765 .{ .type = .usize, .kind = .{ .reg = .rdi } },107596 .{ .type = .usize, .kind = .{ .reg = .rdi } },
107766 .{ .type = .usize, .kind = .{ .reg = .rsi } },107597 .{ .type = .usize, .kind = .{ .reg = .rsi } },
107767 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107598 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107768 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfei" } } },107599 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfei" } },
107769 .unused,107600 .unused,
107770 .unused,107601 .unused,
107771 .unused,107602 .unused,
...@@ -107799,7 +107630,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107799,7 +107630,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107799 .{ .type = .usize, .kind = .{ .reg = .rdi } },107630 .{ .type = .usize, .kind = .{ .reg = .rdi } },
107800 .{ .type = .usize, .kind = .{ .reg = .rsi } },107631 .{ .type = .usize, .kind = .{ .reg = .rsi } },
107801 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107632 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107802 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfei" } } },107633 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfei" } },
107803 .unused,107634 .unused,
107804 .unused,107635 .unused,
107805 .unused,107636 .unused,
...@@ -107833,7 +107664,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107833,7 +107664,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107833 .{ .type = .usize, .kind = .{ .reg = .rdi } },107664 .{ .type = .usize, .kind = .{ .reg = .rdi } },
107834 .{ .type = .usize, .kind = .{ .reg = .rsi } },107665 .{ .type = .usize, .kind = .{ .reg = .rsi } },
107835 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107666 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107836 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfei" } } },107667 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfei" } },
107837 .unused,107668 .unused,
107838 .unused,107669 .unused,
107839 .unused,107670 .unused,
...@@ -107867,7 +107698,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107867,7 +107698,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107867 .{ .type = .usize, .kind = .{ .reg = .rdi } },107698 .{ .type = .usize, .kind = .{ .reg = .rdi } },
107868 .{ .type = .usize, .kind = .{ .reg = .rsi } },107699 .{ .type = .usize, .kind = .{ .reg = .rsi } },
107869 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107700 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107870 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixtfei" } } },107701 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfei" } },
107871 .unused,107702 .unused,
107872 .unused,107703 .unused,
107873 .unused,107704 .unused,
...@@ -107901,7 +107732,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -107901,7 +107732,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
107901 .{ .type = .usize, .kind = .{ .reg = .rdi } },107732 .{ .type = .usize, .kind = .{ .reg = .rdi } },
107902 .{ .type = .usize, .kind = .{ .reg = .rsi } },107733 .{ .type = .usize, .kind = .{ .reg = .rsi } },
107903 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },107734 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
107904 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fixunstfei" } } },107735 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfei" } },
107905 .unused,107736 .unused,
107906 .unused,107737 .unused,
107907 .unused,107738 .unused,
...@@ -108149,7 +107980,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108149,7 +107980,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108149 },107980 },
108150 .call_frame = .{ .alignment = .@"16" },107981 .call_frame = .{ .alignment = .@"16" },
108151 .extra_temps = .{107982 .extra_temps = .{
108152 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },107983 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
108153 .unused,107984 .unused,
108154 .unused,107985 .unused,
108155 .unused,107986 .unused,
...@@ -108176,7 +108007,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108176,7 +108007,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108176 },108007 },
108177 .call_frame = .{ .alignment = .@"16" },108008 .call_frame = .{ .alignment = .@"16" },
108178 .extra_temps = .{108009 .extra_temps = .{
108179 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },108010 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
108180 .unused,108011 .unused,
108181 .unused,108012 .unused,
108182 .unused,108013 .unused,
...@@ -108203,7 +108034,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108203,7 +108034,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108203 },108034 },
108204 .call_frame = .{ .alignment = .@"16" },108035 .call_frame = .{ .alignment = .@"16" },
108205 .extra_temps = .{108036 .extra_temps = .{
108206 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },108037 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
108207 .unused,108038 .unused,
108208 .unused,108039 .unused,
108209 .unused,108040 .unused,
...@@ -108230,7 +108061,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108230,7 +108061,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108230 },108061 },
108231 .call_frame = .{ .alignment = .@"16" },108062 .call_frame = .{ .alignment = .@"16" },
108232 .extra_temps = .{108063 .extra_temps = .{
108233 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },108064 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
108234 .unused,108065 .unused,
108235 .unused,108066 .unused,
108236 .unused,108067 .unused,
...@@ -108257,7 +108088,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108257,7 +108088,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108257 },108088 },
108258 .call_frame = .{ .alignment = .@"16" },108089 .call_frame = .{ .alignment = .@"16" },
108259 .extra_temps = .{108090 .extra_temps = .{
108260 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },108091 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
108261 .unused,108092 .unused,
108262 .unused,108093 .unused,
108263 .unused,108094 .unused,
...@@ -108283,7 +108114,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108283,7 +108114,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108283 },108114 },
108284 .call_frame = .{ .alignment = .@"16" },108115 .call_frame = .{ .alignment = .@"16" },
108285 .extra_temps = .{108116 .extra_temps = .{
108286 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },108117 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
108287 .unused,108118 .unused,
108288 .unused,108119 .unused,
108289 .unused,108120 .unused,
...@@ -108309,7 +108140,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108309,7 +108140,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108309 },108140 },
108310 .call_frame = .{ .alignment = .@"16" },108141 .call_frame = .{ .alignment = .@"16" },
108311 .extra_temps = .{108142 .extra_temps = .{
108312 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatdihf" } } },108143 .{ .type = .usize, .kind = .{ .extern_func = "__floatdihf" } },
108313 .unused,108144 .unused,
108314 .unused,108145 .unused,
108315 .unused,108146 .unused,
...@@ -108335,7 +108166,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108335,7 +108166,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108335 },108166 },
108336 .call_frame = .{ .alignment = .@"16" },108167 .call_frame = .{ .alignment = .@"16" },
108337 .extra_temps = .{108168 .extra_temps = .{
108338 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatundihf" } } },108169 .{ .type = .usize, .kind = .{ .extern_func = "__floatundihf" } },
108339 .unused,108170 .unused,
108340 .unused,108171 .unused,
108341 .unused,108172 .unused,
...@@ -108361,7 +108192,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108361,7 +108192,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108361 },108192 },
108362 .call_frame = .{ .alignment = .@"16" },108193 .call_frame = .{ .alignment = .@"16" },
108363 .extra_temps = .{108194 .extra_temps = .{
108364 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattihf" } } },108195 .{ .type = .usize, .kind = .{ .extern_func = "__floattihf" } },
108365 .unused,108196 .unused,
108366 .unused,108197 .unused,
108367 .unused,108198 .unused,
...@@ -108387,7 +108218,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108387,7 +108218,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108387 },108218 },
108388 .call_frame = .{ .alignment = .@"16" },108219 .call_frame = .{ .alignment = .@"16" },
108389 .extra_temps = .{108220 .extra_temps = .{
108390 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntihf" } } },108221 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntihf" } },
108391 .unused,108222 .unused,
108392 .unused,108223 .unused,
108393 .unused,108224 .unused,
...@@ -108415,7 +108246,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108415,7 +108246,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108415 .extra_temps = .{108246 .extra_temps = .{
108416 .{ .type = .usize, .kind = .{ .reg = .rdi } },108247 .{ .type = .usize, .kind = .{ .reg = .rdi } },
108417 .{ .type = .usize, .kind = .{ .reg = .rsi } },108248 .{ .type = .usize, .kind = .{ .reg = .rsi } },
108418 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateihf" } } },108249 .{ .type = .usize, .kind = .{ .extern_func = "__floateihf" } },
108419 .unused,108250 .unused,
108420 .unused,108251 .unused,
108421 .unused,108252 .unused,
...@@ -108443,7 +108274,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108443,7 +108274,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108443 .extra_temps = .{108274 .extra_temps = .{
108444 .{ .type = .usize, .kind = .{ .reg = .rdi } },108275 .{ .type = .usize, .kind = .{ .reg = .rdi } },
108445 .{ .type = .usize, .kind = .{ .reg = .rsi } },108276 .{ .type = .usize, .kind = .{ .reg = .rsi } },
108446 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneihf" } } },108277 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneihf" } },
108447 .unused,108278 .unused,
108448 .unused,108279 .unused,
108449 .unused,108280 .unused,
...@@ -108647,7 +108478,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108647,7 +108478,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108647 .extra_temps = .{108478 .extra_temps = .{
108648 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108479 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
108649 .{ .type = .i32, .kind = .{ .reg = .edi } },108480 .{ .type = .i32, .kind = .{ .reg = .edi } },
108650 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },108481 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
108651 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108482 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
108652 .unused,108483 .unused,
108653 .unused,108484 .unused,
...@@ -108678,7 +108509,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108678,7 +108509,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108678 .extra_temps = .{108509 .extra_temps = .{
108679 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108510 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
108680 .{ .type = .i32, .kind = .{ .reg = .edi } },108511 .{ .type = .i32, .kind = .{ .reg = .edi } },
108681 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },108512 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
108682 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108513 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
108683 .unused,108514 .unused,
108684 .unused,108515 .unused,
...@@ -108709,7 +108540,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108709,7 +108540,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108709 .extra_temps = .{108540 .extra_temps = .{
108710 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108541 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
108711 .{ .type = .i32, .kind = .{ .reg = .edi } },108542 .{ .type = .i32, .kind = .{ .reg = .edi } },
108712 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },108543 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
108713 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108544 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
108714 .unused,108545 .unused,
108715 .unused,108546 .unused,
...@@ -108740,7 +108571,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108740,7 +108571,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108740 .extra_temps = .{108571 .extra_temps = .{
108741 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108572 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
108742 .{ .type = .i32, .kind = .{ .reg = .edi } },108573 .{ .type = .i32, .kind = .{ .reg = .edi } },
108743 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },108574 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
108744 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108575 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
108745 .unused,108576 .unused,
108746 .unused,108577 .unused,
...@@ -108771,7 +108602,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108771,7 +108602,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108771 .extra_temps = .{108602 .extra_temps = .{
108772 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108603 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
108773 .{ .type = .i32, .kind = .{ .reg = .edi } },108604 .{ .type = .i32, .kind = .{ .reg = .edi } },
108774 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },108605 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
108775 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108606 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
108776 .unused,108607 .unused,
108777 .unused,108608 .unused,
...@@ -108803,7 +108634,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108803,7 +108634,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108803 .extra_temps = .{108634 .extra_temps = .{
108804 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108635 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
108805 .{ .type = .i32, .kind = .{ .reg = .edi } },108636 .{ .type = .i32, .kind = .{ .reg = .edi } },
108806 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },108637 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
108807 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108638 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
108808 .unused,108639 .unused,
108809 .unused,108640 .unused,
...@@ -108835,7 +108666,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108835,7 +108666,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108835 .extra_temps = .{108666 .extra_temps = .{
108836 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108667 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
108837 .{ .type = .i32, .kind = .{ .reg = .edi } },108668 .{ .type = .i32, .kind = .{ .reg = .edi } },
108838 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },108669 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
108839 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108670 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
108840 .{ .type = .f32, .kind = .mem },108671 .{ .type = .f32, .kind = .mem },
108841 .unused,108672 .unused,
...@@ -108868,7 +108699,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108868,7 +108699,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108868 .extra_temps = .{108699 .extra_temps = .{
108869 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108700 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
108870 .{ .type = .i32, .kind = .{ .reg = .edi } },108701 .{ .type = .i32, .kind = .{ .reg = .edi } },
108871 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },108702 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
108872 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108703 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
108873 .{ .type = .f32, .kind = .mem },108704 .{ .type = .f32, .kind = .mem },
108874 .unused,108705 .unused,
...@@ -108901,7 +108732,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108901,7 +108732,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108901 .extra_temps = .{108732 .extra_temps = .{
108902 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108733 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
108903 .{ .type = .u32, .kind = .{ .reg = .edi } },108734 .{ .type = .u32, .kind = .{ .reg = .edi } },
108904 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },108735 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
108905 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108736 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
108906 .unused,108737 .unused,
108907 .unused,108738 .unused,
...@@ -108932,7 +108763,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108932,7 +108763,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108932 .extra_temps = .{108763 .extra_temps = .{
108933 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108764 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
108934 .{ .type = .u32, .kind = .{ .reg = .edi } },108765 .{ .type = .u32, .kind = .{ .reg = .edi } },
108935 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },108766 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
108936 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108767 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
108937 .unused,108768 .unused,
108938 .unused,108769 .unused,
...@@ -108963,7 +108794,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108963,7 +108794,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108963 .extra_temps = .{108794 .extra_temps = .{
108964 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108795 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
108965 .{ .type = .u32, .kind = .{ .reg = .edi } },108796 .{ .type = .u32, .kind = .{ .reg = .edi } },
108966 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },108797 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
108967 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108798 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
108968 .unused,108799 .unused,
108969 .unused,108800 .unused,
...@@ -108994,7 +108825,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -108994,7 +108825,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
108994 .extra_temps = .{108825 .extra_temps = .{
108995 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108826 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
108996 .{ .type = .u32, .kind = .{ .reg = .edi } },108827 .{ .type = .u32, .kind = .{ .reg = .edi } },
108997 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },108828 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
108998 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108829 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
108999 .unused,108830 .unused,
109000 .unused,108831 .unused,
...@@ -109025,7 +108856,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109025,7 +108856,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109025 .extra_temps = .{108856 .extra_temps = .{
109026 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108857 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109027 .{ .type = .u32, .kind = .{ .reg = .edi } },108858 .{ .type = .u32, .kind = .{ .reg = .edi } },
109028 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },108859 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
109029 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108860 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109030 .unused,108861 .unused,
109031 .unused,108862 .unused,
...@@ -109057,7 +108888,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109057,7 +108888,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109057 .extra_temps = .{108888 .extra_temps = .{
109058 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108889 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109059 .{ .type = .u32, .kind = .{ .reg = .edi } },108890 .{ .type = .u32, .kind = .{ .reg = .edi } },
109060 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },108891 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
109061 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108892 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109062 .unused,108893 .unused,
109063 .unused,108894 .unused,
...@@ -109089,7 +108920,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109089,7 +108920,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109089 .extra_temps = .{108920 .extra_temps = .{
109090 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108921 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109091 .{ .type = .u32, .kind = .{ .reg = .edi } },108922 .{ .type = .u32, .kind = .{ .reg = .edi } },
109092 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },108923 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
109093 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108924 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109094 .{ .type = .f32, .kind = .mem },108925 .{ .type = .f32, .kind = .mem },
109095 .unused,108926 .unused,
...@@ -109122,7 +108953,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109122,7 +108953,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109122 .extra_temps = .{108953 .extra_temps = .{
109123 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },108954 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109124 .{ .type = .u32, .kind = .{ .reg = .edi } },108955 .{ .type = .u32, .kind = .{ .reg = .edi } },
109125 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },108956 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
109126 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },108957 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109127 .{ .type = .f32, .kind = .mem },108958 .{ .type = .f32, .kind = .mem },
109128 .unused,108959 .unused,
...@@ -109331,7 +109162,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109331,7 +109162,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109331 .extra_temps = .{109162 .extra_temps = .{
109332 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109163 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109333 .{ .type = .i32, .kind = .{ .reg = .edi } },109164 .{ .type = .i32, .kind = .{ .reg = .edi } },
109334 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },109165 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
109335 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109166 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109336 .unused,109167 .unused,
109337 .unused,109168 .unused,
...@@ -109362,7 +109193,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109362,7 +109193,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109362 .extra_temps = .{109193 .extra_temps = .{
109363 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109194 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109364 .{ .type = .i32, .kind = .{ .reg = .edi } },109195 .{ .type = .i32, .kind = .{ .reg = .edi } },
109365 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },109196 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
109366 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109197 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109367 .unused,109198 .unused,
109368 .unused,109199 .unused,
...@@ -109393,7 +109224,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109393,7 +109224,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109393 .extra_temps = .{109224 .extra_temps = .{
109394 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109225 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109395 .{ .type = .i32, .kind = .{ .reg = .edi } },109226 .{ .type = .i32, .kind = .{ .reg = .edi } },
109396 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },109227 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
109397 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109228 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109398 .unused,109229 .unused,
109399 .unused,109230 .unused,
...@@ -109425,7 +109256,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109425,7 +109256,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109425 .extra_temps = .{109256 .extra_temps = .{
109426 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109257 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109427 .{ .type = .i32, .kind = .{ .reg = .edi } },109258 .{ .type = .i32, .kind = .{ .reg = .edi } },
109428 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },109259 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
109429 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109260 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109430 .{ .type = .f32, .kind = .mem },109261 .{ .type = .f32, .kind = .mem },
109431 .unused,109262 .unused,
...@@ -109458,7 +109289,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109458,7 +109289,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109458 .extra_temps = .{109289 .extra_temps = .{
109459 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109290 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109460 .{ .type = .u32, .kind = .{ .reg = .edi } },109291 .{ .type = .u32, .kind = .{ .reg = .edi } },
109461 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },109292 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
109462 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109293 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109463 .unused,109294 .unused,
109464 .unused,109295 .unused,
...@@ -109489,7 +109320,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109489,7 +109320,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109489 .extra_temps = .{109320 .extra_temps = .{
109490 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109321 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109491 .{ .type = .u32, .kind = .{ .reg = .edi } },109322 .{ .type = .u32, .kind = .{ .reg = .edi } },
109492 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },109323 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
109493 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109324 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109494 .unused,109325 .unused,
109495 .unused,109326 .unused,
...@@ -109520,7 +109351,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109520,7 +109351,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109520 .extra_temps = .{109351 .extra_temps = .{
109521 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109352 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109522 .{ .type = .u32, .kind = .{ .reg = .edi } },109353 .{ .type = .u32, .kind = .{ .reg = .edi } },
109523 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },109354 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
109524 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109355 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109525 .unused,109356 .unused,
109526 .unused,109357 .unused,
...@@ -109552,7 +109383,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109552,7 +109383,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109552 .extra_temps = .{109383 .extra_temps = .{
109553 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109384 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109554 .{ .type = .u32, .kind = .{ .reg = .edi } },109385 .{ .type = .u32, .kind = .{ .reg = .edi } },
109555 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },109386 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
109556 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109387 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109557 .{ .type = .f32, .kind = .mem },109388 .{ .type = .f32, .kind = .mem },
109558 .unused,109389 .unused,
...@@ -109669,7 +109500,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109669,7 +109500,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109669 .extra_temps = .{109500 .extra_temps = .{
109670 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109501 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109671 .{ .type = .i32, .kind = .{ .reg = .edi } },109502 .{ .type = .i32, .kind = .{ .reg = .edi } },
109672 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },109503 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
109673 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109504 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109674 .unused,109505 .unused,
109675 .unused,109506 .unused,
...@@ -109700,7 +109531,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109700,7 +109531,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109700 .extra_temps = .{109531 .extra_temps = .{
109701 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109532 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109702 .{ .type = .i32, .kind = .{ .reg = .edi } },109533 .{ .type = .i32, .kind = .{ .reg = .edi } },
109703 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },109534 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
109704 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109535 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109705 .unused,109536 .unused,
109706 .unused,109537 .unused,
...@@ -109731,7 +109562,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109731,7 +109562,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109731 .extra_temps = .{109562 .extra_temps = .{
109732 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109563 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109733 .{ .type = .i32, .kind = .{ .reg = .edi } },109564 .{ .type = .i32, .kind = .{ .reg = .edi } },
109734 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },109565 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
109735 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109566 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109736 .unused,109567 .unused,
109737 .unused,109568 .unused,
...@@ -109763,7 +109594,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109763,7 +109594,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109763 .extra_temps = .{109594 .extra_temps = .{
109764 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109595 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109765 .{ .type = .i32, .kind = .{ .reg = .edi } },109596 .{ .type = .i32, .kind = .{ .reg = .edi } },
109766 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsihf" } } },109597 .{ .type = .usize, .kind = .{ .extern_func = "__floatsihf" } },
109767 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109598 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109768 .{ .type = .f32, .kind = .mem },109599 .{ .type = .f32, .kind = .mem },
109769 .unused,109600 .unused,
...@@ -109796,7 +109627,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109796,7 +109627,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109796 .extra_temps = .{109627 .extra_temps = .{
109797 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109628 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109798 .{ .type = .u32, .kind = .{ .reg = .edi } },109629 .{ .type = .u32, .kind = .{ .reg = .edi } },
109799 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },109630 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
109800 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109631 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109801 .unused,109632 .unused,
109802 .unused,109633 .unused,
...@@ -109827,7 +109658,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109827,7 +109658,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109827 .extra_temps = .{109658 .extra_temps = .{
109828 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109659 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109829 .{ .type = .u32, .kind = .{ .reg = .edi } },109660 .{ .type = .u32, .kind = .{ .reg = .edi } },
109830 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },109661 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
109831 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109662 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109832 .unused,109663 .unused,
109833 .unused,109664 .unused,
...@@ -109858,7 +109689,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109858,7 +109689,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109858 .extra_temps = .{109689 .extra_temps = .{
109859 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109690 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109860 .{ .type = .u32, .kind = .{ .reg = .edi } },109691 .{ .type = .u32, .kind = .{ .reg = .edi } },
109861 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },109692 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
109862 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109693 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109863 .unused,109694 .unused,
109864 .unused,109695 .unused,
...@@ -109890,7 +109721,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109890,7 +109721,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109890 .extra_temps = .{109721 .extra_temps = .{
109891 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109722 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109892 .{ .type = .u32, .kind = .{ .reg = .edi } },109723 .{ .type = .u32, .kind = .{ .reg = .edi } },
109893 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsihf" } } },109724 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsihf" } },
109894 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109725 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109895 .{ .type = .f32, .kind = .mem },109726 .{ .type = .f32, .kind = .mem },
109896 .unused,109727 .unused,
...@@ -109954,7 +109785,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109954,7 +109785,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109954 .extra_temps = .{109785 .extra_temps = .{
109955 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109786 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109956 .{ .type = .i64, .kind = .{ .reg = .rdi } },109787 .{ .type = .i64, .kind = .{ .reg = .rdi } },
109957 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatdihf" } } },109788 .{ .type = .usize, .kind = .{ .extern_func = "__floatdihf" } },
109958 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109789 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109959 .unused,109790 .unused,
109960 .unused,109791 .unused,
...@@ -109985,7 +109816,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -109985,7 +109816,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
109985 .extra_temps = .{109816 .extra_temps = .{
109986 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109817 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
109987 .{ .type = .i64, .kind = .{ .reg = .rdi } },109818 .{ .type = .i64, .kind = .{ .reg = .rdi } },
109988 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatdihf" } } },109819 .{ .type = .usize, .kind = .{ .extern_func = "__floatdihf" } },
109989 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109820 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
109990 .unused,109821 .unused,
109991 .unused,109822 .unused,
...@@ -110016,7 +109847,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110016,7 +109847,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110016 .extra_temps = .{109847 .extra_temps = .{
110017 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109848 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110018 .{ .type = .i64, .kind = .{ .reg = .rdi } },109849 .{ .type = .i64, .kind = .{ .reg = .rdi } },
110019 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatdihf" } } },109850 .{ .type = .usize, .kind = .{ .extern_func = "__floatdihf" } },
110020 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109851 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110021 .unused,109852 .unused,
110022 .unused,109853 .unused,
...@@ -110048,7 +109879,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110048,7 +109879,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110048 .extra_temps = .{109879 .extra_temps = .{
110049 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109880 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110050 .{ .type = .i64, .kind = .{ .reg = .rdi } },109881 .{ .type = .i64, .kind = .{ .reg = .rdi } },
110051 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatdihf" } } },109882 .{ .type = .usize, .kind = .{ .extern_func = "__floatdihf" } },
110052 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109883 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110053 .{ .type = .f32, .kind = .mem },109884 .{ .type = .f32, .kind = .mem },
110054 .unused,109885 .unused,
...@@ -110081,7 +109912,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110081,7 +109912,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110081 .extra_temps = .{109912 .extra_temps = .{
110082 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109913 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110083 .{ .type = .u64, .kind = .{ .reg = .rdi } },109914 .{ .type = .u64, .kind = .{ .reg = .rdi } },
110084 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatundihf" } } },109915 .{ .type = .usize, .kind = .{ .extern_func = "__floatundihf" } },
110085 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109916 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110086 .unused,109917 .unused,
110087 .unused,109918 .unused,
...@@ -110112,7 +109943,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110112,7 +109943,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110112 .extra_temps = .{109943 .extra_temps = .{
110113 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109944 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110114 .{ .type = .u64, .kind = .{ .reg = .rdi } },109945 .{ .type = .u64, .kind = .{ .reg = .rdi } },
110115 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatundihf" } } },109946 .{ .type = .usize, .kind = .{ .extern_func = "__floatundihf" } },
110116 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109947 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110117 .unused,109948 .unused,
110118 .unused,109949 .unused,
...@@ -110143,7 +109974,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110143,7 +109974,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110143 .extra_temps = .{109974 .extra_temps = .{
110144 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },109975 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110145 .{ .type = .u64, .kind = .{ .reg = .rdi } },109976 .{ .type = .u64, .kind = .{ .reg = .rdi } },
110146 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatundihf" } } },109977 .{ .type = .usize, .kind = .{ .extern_func = "__floatundihf" } },
110147 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },109978 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110148 .unused,109979 .unused,
110149 .unused,109980 .unused,
...@@ -110175,7 +110006,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110175,7 +110006,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110175 .extra_temps = .{110006 .extra_temps = .{
110176 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110007 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110177 .{ .type = .u64, .kind = .{ .reg = .rdi } },110008 .{ .type = .u64, .kind = .{ .reg = .rdi } },
110178 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatundihf" } } },110009 .{ .type = .usize, .kind = .{ .extern_func = "__floatundihf" } },
110179 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110010 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110180 .{ .type = .f32, .kind = .mem },110011 .{ .type = .f32, .kind = .mem },
110181 .unused,110012 .unused,
...@@ -110209,7 +110040,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110209,7 +110040,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110209 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110040 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110210 .{ .type = .u64, .kind = .{ .reg = .rdi } },110041 .{ .type = .u64, .kind = .{ .reg = .rdi } },
110211 .{ .type = .i64, .kind = .{ .reg = .rsi } },110042 .{ .type = .i64, .kind = .{ .reg = .rsi } },
110212 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattihf" } } },110043 .{ .type = .usize, .kind = .{ .extern_func = "__floattihf" } },
110213 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110044 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110214 .unused,110045 .unused,
110215 .unused,110046 .unused,
...@@ -110241,7 +110072,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110241,7 +110072,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110241 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110072 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110242 .{ .type = .u64, .kind = .{ .reg = .rdi } },110073 .{ .type = .u64, .kind = .{ .reg = .rdi } },
110243 .{ .type = .i64, .kind = .{ .reg = .rsi } },110074 .{ .type = .i64, .kind = .{ .reg = .rsi } },
110244 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattihf" } } },110075 .{ .type = .usize, .kind = .{ .extern_func = "__floattihf" } },
110245 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110076 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110246 .unused,110077 .unused,
110247 .unused,110078 .unused,
...@@ -110273,7 +110104,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110273,7 +110104,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110273 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110104 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110274 .{ .type = .u64, .kind = .{ .reg = .rdi } },110105 .{ .type = .u64, .kind = .{ .reg = .rdi } },
110275 .{ .type = .i64, .kind = .{ .reg = .rsi } },110106 .{ .type = .i64, .kind = .{ .reg = .rsi } },
110276 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattihf" } } },110107 .{ .type = .usize, .kind = .{ .extern_func = "__floattihf" } },
110277 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110108 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110278 .unused,110109 .unused,
110279 .unused,110110 .unused,
...@@ -110306,7 +110137,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110306,7 +110137,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110306 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110137 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110307 .{ .type = .u64, .kind = .{ .reg = .rdi } },110138 .{ .type = .u64, .kind = .{ .reg = .rdi } },
110308 .{ .type = .i64, .kind = .{ .reg = .rsi } },110139 .{ .type = .i64, .kind = .{ .reg = .rsi } },
110309 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattihf" } } },110140 .{ .type = .usize, .kind = .{ .extern_func = "__floattihf" } },
110310 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110141 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110311 .{ .type = .f32, .kind = .mem },110142 .{ .type = .f32, .kind = .mem },
110312 .unused,110143 .unused,
...@@ -110340,7 +110171,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110340,7 +110171,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110340 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110171 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110341 .{ .type = .u64, .kind = .{ .reg = .rdi } },110172 .{ .type = .u64, .kind = .{ .reg = .rdi } },
110342 .{ .type = .u64, .kind = .{ .reg = .rsi } },110173 .{ .type = .u64, .kind = .{ .reg = .rsi } },
110343 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntihf" } } },110174 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntihf" } },
110344 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110175 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110345 .unused,110176 .unused,
110346 .unused,110177 .unused,
...@@ -110372,7 +110203,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110372,7 +110203,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110372 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110203 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110373 .{ .type = .u64, .kind = .{ .reg = .rdi } },110204 .{ .type = .u64, .kind = .{ .reg = .rdi } },
110374 .{ .type = .u64, .kind = .{ .reg = .rsi } },110205 .{ .type = .u64, .kind = .{ .reg = .rsi } },
110375 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntihf" } } },110206 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntihf" } },
110376 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110207 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110377 .unused,110208 .unused,
110378 .unused,110209 .unused,
...@@ -110404,7 +110235,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110404,7 +110235,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110404 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110235 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110405 .{ .type = .u64, .kind = .{ .reg = .rdi } },110236 .{ .type = .u64, .kind = .{ .reg = .rdi } },
110406 .{ .type = .u64, .kind = .{ .reg = .rsi } },110237 .{ .type = .u64, .kind = .{ .reg = .rsi } },
110407 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntihf" } } },110238 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntihf" } },
110408 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110239 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110409 .unused,110240 .unused,
110410 .unused,110241 .unused,
...@@ -110437,7 +110268,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110437,7 +110268,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110437 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110268 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110438 .{ .type = .u64, .kind = .{ .reg = .rdi } },110269 .{ .type = .u64, .kind = .{ .reg = .rdi } },
110439 .{ .type = .u64, .kind = .{ .reg = .rsi } },110270 .{ .type = .u64, .kind = .{ .reg = .rsi } },
110440 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntihf" } } },110271 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntihf" } },
110441 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110272 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110442 .{ .type = .f32, .kind = .mem },110273 .{ .type = .f32, .kind = .mem },
110443 .unused,110274 .unused,
...@@ -110472,7 +110303,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110472,7 +110303,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110472 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110303 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110473 .{ .type = .usize, .kind = .{ .reg = .rdi } },110304 .{ .type = .usize, .kind = .{ .reg = .rdi } },
110474 .{ .type = .usize, .kind = .{ .reg = .rsi } },110305 .{ .type = .usize, .kind = .{ .reg = .rsi } },
110475 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateihf" } } },110306 .{ .type = .usize, .kind = .{ .extern_func = "__floateihf" } },
110476 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110307 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110477 .unused,110308 .unused,
110478 .unused,110309 .unused,
...@@ -110506,7 +110337,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110506,7 +110337,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110506 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110337 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110507 .{ .type = .usize, .kind = .{ .reg = .rdi } },110338 .{ .type = .usize, .kind = .{ .reg = .rdi } },
110508 .{ .type = .usize, .kind = .{ .reg = .rsi } },110339 .{ .type = .usize, .kind = .{ .reg = .rsi } },
110509 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateihf" } } },110340 .{ .type = .usize, .kind = .{ .extern_func = "__floateihf" } },
110510 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110341 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110511 .unused,110342 .unused,
110512 .unused,110343 .unused,
...@@ -110540,7 +110371,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110540,7 +110371,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110540 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110371 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110541 .{ .type = .usize, .kind = .{ .reg = .rdi } },110372 .{ .type = .usize, .kind = .{ .reg = .rdi } },
110542 .{ .type = .usize, .kind = .{ .reg = .rsi } },110373 .{ .type = .usize, .kind = .{ .reg = .rsi } },
110543 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateihf" } } },110374 .{ .type = .usize, .kind = .{ .extern_func = "__floateihf" } },
110544 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110375 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110545 .unused,110376 .unused,
110546 .unused,110377 .unused,
...@@ -110575,7 +110406,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110575,7 +110406,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110575 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110406 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110576 .{ .type = .usize, .kind = .{ .reg = .rdi } },110407 .{ .type = .usize, .kind = .{ .reg = .rdi } },
110577 .{ .type = .usize, .kind = .{ .reg = .rsi } },110408 .{ .type = .usize, .kind = .{ .reg = .rsi } },
110578 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateihf" } } },110409 .{ .type = .usize, .kind = .{ .extern_func = "__floateihf" } },
110579 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110410 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110580 .{ .type = .f32, .kind = .mem },110411 .{ .type = .f32, .kind = .mem },
110581 .unused,110412 .unused,
...@@ -110611,7 +110442,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110611,7 +110442,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110611 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110442 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110612 .{ .type = .usize, .kind = .{ .reg = .rdi } },110443 .{ .type = .usize, .kind = .{ .reg = .rdi } },
110613 .{ .type = .usize, .kind = .{ .reg = .rsi } },110444 .{ .type = .usize, .kind = .{ .reg = .rsi } },
110614 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneihf" } } },110445 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneihf" } },
110615 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110446 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110616 .unused,110447 .unused,
110617 .unused,110448 .unused,
...@@ -110645,7 +110476,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110645,7 +110476,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110645 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110476 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110646 .{ .type = .usize, .kind = .{ .reg = .rdi } },110477 .{ .type = .usize, .kind = .{ .reg = .rdi } },
110647 .{ .type = .usize, .kind = .{ .reg = .rsi } },110478 .{ .type = .usize, .kind = .{ .reg = .rsi } },
110648 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneihf" } } },110479 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneihf" } },
110649 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110480 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110650 .unused,110481 .unused,
110651 .unused,110482 .unused,
...@@ -110679,7 +110510,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110679,7 +110510,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110679 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110510 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110680 .{ .type = .usize, .kind = .{ .reg = .rdi } },110511 .{ .type = .usize, .kind = .{ .reg = .rdi } },
110681 .{ .type = .usize, .kind = .{ .reg = .rsi } },110512 .{ .type = .usize, .kind = .{ .reg = .rsi } },
110682 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneihf" } } },110513 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneihf" } },
110683 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110514 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110684 .unused,110515 .unused,
110685 .unused,110516 .unused,
...@@ -110714,7 +110545,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -110714,7 +110545,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110714 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },110545 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
110715 .{ .type = .usize, .kind = .{ .reg = .rdi } },110546 .{ .type = .usize, .kind = .{ .reg = .rdi } },
110716 .{ .type = .usize, .kind = .{ .reg = .rsi } },110547 .{ .type = .usize, .kind = .{ .reg = .rsi } },
110717 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneihf" } } },110548 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneihf" } },
110718 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },110549 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
110719 .{ .type = .f32, .kind = .mem },110550 .{ .type = .f32, .kind = .mem },
110720 .unused,110551 .unused,
...@@ -111138,7 +110969,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -111138,7 +110969,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111138 },110969 },
111139 .call_frame = .{ .alignment = .@"16" },110970 .call_frame = .{ .alignment = .@"16" },
111140 .extra_temps = .{110971 .extra_temps = .{
111141 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattisf" } } },110972 .{ .type = .usize, .kind = .{ .extern_func = "__floattisf" } },
111142 .unused,110973 .unused,
111143 .unused,110974 .unused,
111144 .unused,110975 .unused,
...@@ -111164,7 +110995,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -111164,7 +110995,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111164 },110995 },
111165 .call_frame = .{ .alignment = .@"16" },110996 .call_frame = .{ .alignment = .@"16" },
111166 .extra_temps = .{110997 .extra_temps = .{
111167 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntisf" } } },110998 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntisf" } },
111168 .unused,110999 .unused,
111169 .unused,111000 .unused,
111170 .unused,111001 .unused,
...@@ -111192,7 +111023,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -111192,7 +111023,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111192 .extra_temps = .{111023 .extra_temps = .{
111193 .{ .type = .usize, .kind = .{ .reg = .rdi } },111024 .{ .type = .usize, .kind = .{ .reg = .rdi } },
111194 .{ .type = .usize, .kind = .{ .reg = .rsi } },111025 .{ .type = .usize, .kind = .{ .reg = .rsi } },
111195 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateisf" } } },111026 .{ .type = .usize, .kind = .{ .extern_func = "__floateisf" } },
111196 .unused,111027 .unused,
111197 .unused,111028 .unused,
111198 .unused,111029 .unused,
...@@ -111220,7 +111051,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -111220,7 +111051,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111220 .extra_temps = .{111051 .extra_temps = .{
111221 .{ .type = .usize, .kind = .{ .reg = .rdi } },111052 .{ .type = .usize, .kind = .{ .reg = .rdi } },
111222 .{ .type = .usize, .kind = .{ .reg = .rsi } },111053 .{ .type = .usize, .kind = .{ .reg = .rsi } },
111223 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneisf" } } },111054 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneisf" } },
111224 .unused,111055 .unused,
111225 .unused,111056 .unused,
111226 .unused,111057 .unused,
...@@ -111506,7 +111337,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -111506,7 +111337,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111506 .extra_temps = .{111337 .extra_temps = .{
111507 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },111338 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
111508 .{ .type = .i32, .kind = .{ .reg = .edi } },111339 .{ .type = .i32, .kind = .{ .reg = .edi } },
111509 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsisf" } } },111340 .{ .type = .usize, .kind = .{ .extern_func = "__floatsisf" } },
111510 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },111341 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
111511 .unused,111342 .unused,
111512 .unused,111343 .unused,
...@@ -111537,7 +111368,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -111537,7 +111368,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111537 .extra_temps = .{111368 .extra_temps = .{
111538 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },111369 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
111539 .{ .type = .i32, .kind = .{ .reg = .edi } },111370 .{ .type = .i32, .kind = .{ .reg = .edi } },
111540 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsisf" } } },111371 .{ .type = .usize, .kind = .{ .extern_func = "__floatsisf" } },
111541 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },111372 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
111542 .unused,111373 .unused,
111543 .unused,111374 .unused,
...@@ -111568,7 +111399,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -111568,7 +111399,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111568 .extra_temps = .{111399 .extra_temps = .{
111569 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },111400 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
111570 .{ .type = .i32, .kind = .{ .reg = .edi } },111401 .{ .type = .i32, .kind = .{ .reg = .edi } },
111571 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsisf" } } },111402 .{ .type = .usize, .kind = .{ .extern_func = "__floatsisf" } },
111572 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },111403 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
111573 .unused,111404 .unused,
111574 .unused,111405 .unused,
...@@ -111599,7 +111430,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -111599,7 +111430,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111599 .extra_temps = .{111430 .extra_temps = .{
111600 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },111431 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
111601 .{ .type = .i32, .kind = .{ .reg = .edi } },111432 .{ .type = .i32, .kind = .{ .reg = .edi } },
111602 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsisf" } } },111433 .{ .type = .usize, .kind = .{ .extern_func = "__floatsisf" } },
111603 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },111434 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
111604 .unused,111435 .unused,
111605 .unused,111436 .unused,
...@@ -111630,7 +111461,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -111630,7 +111461,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111630 .extra_temps = .{111461 .extra_temps = .{
111631 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },111462 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
111632 .{ .type = .u32, .kind = .{ .reg = .edi } },111463 .{ .type = .u32, .kind = .{ .reg = .edi } },
111633 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsisf" } } },111464 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsisf" } },
111634 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },111465 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
111635 .unused,111466 .unused,
111636 .unused,111467 .unused,
...@@ -111661,7 +111492,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -111661,7 +111492,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111661 .extra_temps = .{111492 .extra_temps = .{
111662 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },111493 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
111663 .{ .type = .u32, .kind = .{ .reg = .edi } },111494 .{ .type = .u32, .kind = .{ .reg = .edi } },
111664 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsisf" } } },111495 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsisf" } },
111665 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },111496 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
111666 .unused,111497 .unused,
111667 .unused,111498 .unused,
...@@ -111692,7 +111523,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -111692,7 +111523,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111692 .extra_temps = .{111523 .extra_temps = .{
111693 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },111524 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
111694 .{ .type = .u32, .kind = .{ .reg = .edi } },111525 .{ .type = .u32, .kind = .{ .reg = .edi } },
111695 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsisf" } } },111526 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsisf" } },
111696 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },111527 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
111697 .unused,111528 .unused,
111698 .unused,111529 .unused,
...@@ -111723,7 +111554,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -111723,7 +111554,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111723 .extra_temps = .{111554 .extra_temps = .{
111724 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },111555 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
111725 .{ .type = .u32, .kind = .{ .reg = .edi } },111556 .{ .type = .u32, .kind = .{ .reg = .edi } },
111726 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsisf" } } },111557 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsisf" } },
111727 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },111558 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
111728 .unused,111559 .unused,
111729 .unused,111560 .unused,
...@@ -112012,7 +111843,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112012,7 +111843,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112012 .extra_temps = .{111843 .extra_temps = .{
112013 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },111844 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112014 .{ .type = .i32, .kind = .{ .reg = .edi } },111845 .{ .type = .i32, .kind = .{ .reg = .edi } },
112015 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsisf" } } },111846 .{ .type = .usize, .kind = .{ .extern_func = "__floatsisf" } },
112016 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },111847 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112017 .unused,111848 .unused,
112018 .unused,111849 .unused,
...@@ -112043,7 +111874,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112043,7 +111874,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112043 .extra_temps = .{111874 .extra_temps = .{
112044 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },111875 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112045 .{ .type = .i32, .kind = .{ .reg = .edi } },111876 .{ .type = .i32, .kind = .{ .reg = .edi } },
112046 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsisf" } } },111877 .{ .type = .usize, .kind = .{ .extern_func = "__floatsisf" } },
112047 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },111878 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112048 .unused,111879 .unused,
112049 .unused,111880 .unused,
...@@ -112074,7 +111905,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112074,7 +111905,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112074 .extra_temps = .{111905 .extra_temps = .{
112075 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },111906 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112076 .{ .type = .u32, .kind = .{ .reg = .edi } },111907 .{ .type = .u32, .kind = .{ .reg = .edi } },
112077 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsisf" } } },111908 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsisf" } },
112078 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },111909 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112079 .unused,111910 .unused,
112080 .unused,111911 .unused,
...@@ -112105,7 +111936,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112105,7 +111936,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112105 .extra_temps = .{111936 .extra_temps = .{
112106 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },111937 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112107 .{ .type = .u32, .kind = .{ .reg = .edi } },111938 .{ .type = .u32, .kind = .{ .reg = .edi } },
112108 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsisf" } } },111939 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsisf" } },
112109 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },111940 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112110 .unused,111941 .unused,
112111 .unused,111942 .unused,
...@@ -112288,7 +112119,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112288,7 +112119,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112288 .extra_temps = .{112119 .extra_temps = .{
112289 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112120 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112290 .{ .type = .i32, .kind = .{ .reg = .edi } },112121 .{ .type = .i32, .kind = .{ .reg = .edi } },
112291 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsisf" } } },112122 .{ .type = .usize, .kind = .{ .extern_func = "__floatsisf" } },
112292 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112123 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112293 .unused,112124 .unused,
112294 .unused,112125 .unused,
...@@ -112319,7 +112150,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112319,7 +112150,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112319 .extra_temps = .{112150 .extra_temps = .{
112320 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112151 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112321 .{ .type = .i32, .kind = .{ .reg = .edi } },112152 .{ .type = .i32, .kind = .{ .reg = .edi } },
112322 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsisf" } } },112153 .{ .type = .usize, .kind = .{ .extern_func = "__floatsisf" } },
112323 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112154 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112324 .unused,112155 .unused,
112325 .unused,112156 .unused,
...@@ -112350,7 +112181,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112350,7 +112181,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112350 .extra_temps = .{112181 .extra_temps = .{
112351 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112182 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112352 .{ .type = .u32, .kind = .{ .reg = .edi } },112183 .{ .type = .u32, .kind = .{ .reg = .edi } },
112353 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsisf" } } },112184 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsisf" } },
112354 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112185 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112355 .unused,112186 .unused,
112356 .unused,112187 .unused,
...@@ -112381,7 +112212,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112381,7 +112212,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112381 .extra_temps = .{112212 .extra_temps = .{
112382 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112213 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112383 .{ .type = .u32, .kind = .{ .reg = .edi } },112214 .{ .type = .u32, .kind = .{ .reg = .edi } },
112384 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsisf" } } },112215 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsisf" } },
112385 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112216 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112386 .unused,112217 .unused,
112387 .unused,112218 .unused,
...@@ -112472,7 +112303,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112472,7 +112303,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112472 .extra_temps = .{112303 .extra_temps = .{
112473 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112304 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112474 .{ .type = .i64, .kind = .{ .reg = .rdi } },112305 .{ .type = .i64, .kind = .{ .reg = .rdi } },
112475 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatdisf" } } },112306 .{ .type = .usize, .kind = .{ .extern_func = "__floatdisf" } },
112476 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112307 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112477 .unused,112308 .unused,
112478 .unused,112309 .unused,
...@@ -112503,7 +112334,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112503,7 +112334,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112503 .extra_temps = .{112334 .extra_temps = .{
112504 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112335 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112505 .{ .type = .i64, .kind = .{ .reg = .rdi } },112336 .{ .type = .i64, .kind = .{ .reg = .rdi } },
112506 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatdisf" } } },112337 .{ .type = .usize, .kind = .{ .extern_func = "__floatdisf" } },
112507 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112338 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112508 .unused,112339 .unused,
112509 .unused,112340 .unused,
...@@ -112534,7 +112365,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112534,7 +112365,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112534 .extra_temps = .{112365 .extra_temps = .{
112535 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112366 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112536 .{ .type = .u64, .kind = .{ .reg = .rdi } },112367 .{ .type = .u64, .kind = .{ .reg = .rdi } },
112537 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatundisf" } } },112368 .{ .type = .usize, .kind = .{ .extern_func = "__floatundisf" } },
112538 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112369 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112539 .unused,112370 .unused,
112540 .unused,112371 .unused,
...@@ -112565,7 +112396,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112565,7 +112396,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112565 .extra_temps = .{112396 .extra_temps = .{
112566 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112397 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112567 .{ .type = .u64, .kind = .{ .reg = .rdi } },112398 .{ .type = .u64, .kind = .{ .reg = .rdi } },
112568 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatundisf" } } },112399 .{ .type = .usize, .kind = .{ .extern_func = "__floatundisf" } },
112569 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112400 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112570 .unused,112401 .unused,
112571 .unused,112402 .unused,
...@@ -112597,7 +112428,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112597,7 +112428,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112597 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112428 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112598 .{ .type = .u64, .kind = .{ .reg = .rdi } },112429 .{ .type = .u64, .kind = .{ .reg = .rdi } },
112599 .{ .type = .i64, .kind = .{ .reg = .rsi } },112430 .{ .type = .i64, .kind = .{ .reg = .rsi } },
112600 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattisf" } } },112431 .{ .type = .usize, .kind = .{ .extern_func = "__floattisf" } },
112601 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112432 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112602 .unused,112433 .unused,
112603 .unused,112434 .unused,
...@@ -112629,7 +112460,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112629,7 +112460,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112629 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112460 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112630 .{ .type = .u64, .kind = .{ .reg = .rdi } },112461 .{ .type = .u64, .kind = .{ .reg = .rdi } },
112631 .{ .type = .i64, .kind = .{ .reg = .rsi } },112462 .{ .type = .i64, .kind = .{ .reg = .rsi } },
112632 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattisf" } } },112463 .{ .type = .usize, .kind = .{ .extern_func = "__floattisf" } },
112633 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112464 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112634 .unused,112465 .unused,
112635 .unused,112466 .unused,
...@@ -112661,7 +112492,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112661,7 +112492,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112661 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112492 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112662 .{ .type = .u64, .kind = .{ .reg = .rdi } },112493 .{ .type = .u64, .kind = .{ .reg = .rdi } },
112663 .{ .type = .u64, .kind = .{ .reg = .rsi } },112494 .{ .type = .u64, .kind = .{ .reg = .rsi } },
112664 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntisf" } } },112495 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntisf" } },
112665 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112496 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112666 .unused,112497 .unused,
112667 .unused,112498 .unused,
...@@ -112693,7 +112524,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112693,7 +112524,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112693 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112524 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112694 .{ .type = .u64, .kind = .{ .reg = .rdi } },112525 .{ .type = .u64, .kind = .{ .reg = .rdi } },
112695 .{ .type = .u64, .kind = .{ .reg = .rsi } },112526 .{ .type = .u64, .kind = .{ .reg = .rsi } },
112696 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntisf" } } },112527 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntisf" } },
112697 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112528 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112698 .unused,112529 .unused,
112699 .unused,112530 .unused,
...@@ -112726,7 +112557,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112726,7 +112557,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112726 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112557 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112727 .{ .type = .usize, .kind = .{ .reg = .rdi } },112558 .{ .type = .usize, .kind = .{ .reg = .rdi } },
112728 .{ .type = .usize, .kind = .{ .reg = .rsi } },112559 .{ .type = .usize, .kind = .{ .reg = .rsi } },
112729 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateisf" } } },112560 .{ .type = .usize, .kind = .{ .extern_func = "__floateisf" } },
112730 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112561 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112731 .unused,112562 .unused,
112732 .unused,112563 .unused,
...@@ -112760,7 +112591,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112760,7 +112591,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112760 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112591 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112761 .{ .type = .usize, .kind = .{ .reg = .rdi } },112592 .{ .type = .usize, .kind = .{ .reg = .rdi } },
112762 .{ .type = .usize, .kind = .{ .reg = .rsi } },112593 .{ .type = .usize, .kind = .{ .reg = .rsi } },
112763 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateisf" } } },112594 .{ .type = .usize, .kind = .{ .extern_func = "__floateisf" } },
112764 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112595 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112765 .unused,112596 .unused,
112766 .unused,112597 .unused,
...@@ -112794,7 +112625,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112794,7 +112625,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112794 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112625 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112795 .{ .type = .usize, .kind = .{ .reg = .rdi } },112626 .{ .type = .usize, .kind = .{ .reg = .rdi } },
112796 .{ .type = .usize, .kind = .{ .reg = .rsi } },112627 .{ .type = .usize, .kind = .{ .reg = .rsi } },
112797 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneisf" } } },112628 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneisf" } },
112798 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112629 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112799 .unused,112630 .unused,
112800 .unused,112631 .unused,
...@@ -112828,7 +112659,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -112828,7 +112659,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112828 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },112659 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
112829 .{ .type = .usize, .kind = .{ .reg = .rdi } },112660 .{ .type = .usize, .kind = .{ .reg = .rdi } },
112830 .{ .type = .usize, .kind = .{ .reg = .rsi } },112661 .{ .type = .usize, .kind = .{ .reg = .rsi } },
112831 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneisf" } } },112662 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneisf" } },
112832 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },112663 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
112833 .unused,112664 .unused,
112834 .unused,112665 .unused,
...@@ -113468,7 +113299,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -113468,7 +113299,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
113468 },113299 },
113469 .call_frame = .{ .alignment = .@"16" },113300 .call_frame = .{ .alignment = .@"16" },
113470 .extra_temps = .{113301 .extra_temps = .{
113471 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattidf" } } },113302 .{ .type = .usize, .kind = .{ .extern_func = "__floattidf" } },
113472 .unused,113303 .unused,
113473 .unused,113304 .unused,
113474 .unused,113305 .unused,
...@@ -113494,7 +113325,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -113494,7 +113325,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
113494 },113325 },
113495 .call_frame = .{ .alignment = .@"16" },113326 .call_frame = .{ .alignment = .@"16" },
113496 .extra_temps = .{113327 .extra_temps = .{
113497 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntidf" } } },113328 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntidf" } },
113498 .unused,113329 .unused,
113499 .unused,113330 .unused,
113500 .unused,113331 .unused,
...@@ -113522,7 +113353,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -113522,7 +113353,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
113522 .extra_temps = .{113353 .extra_temps = .{
113523 .{ .type = .usize, .kind = .{ .reg = .rdi } },113354 .{ .type = .usize, .kind = .{ .reg = .rdi } },
113524 .{ .type = .usize, .kind = .{ .reg = .rsi } },113355 .{ .type = .usize, .kind = .{ .reg = .rsi } },
113525 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateidf" } } },113356 .{ .type = .usize, .kind = .{ .extern_func = "__floateidf" } },
113526 .unused,113357 .unused,
113527 .unused,113358 .unused,
113528 .unused,113359 .unused,
...@@ -113550,7 +113381,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -113550,7 +113381,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
113550 .extra_temps = .{113381 .extra_temps = .{
113551 .{ .type = .usize, .kind = .{ .reg = .rdi } },113382 .{ .type = .usize, .kind = .{ .reg = .rdi } },
113552 .{ .type = .usize, .kind = .{ .reg = .rsi } },113383 .{ .type = .usize, .kind = .{ .reg = .rsi } },
113553 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneidf" } } },113384 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneidf" } },
113554 .unused,113385 .unused,
113555 .unused,113386 .unused,
113556 .unused,113387 .unused,
...@@ -113844,7 +113675,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -113844,7 +113675,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
113844 .extra_temps = .{113675 .extra_temps = .{
113845 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },113676 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
113846 .{ .type = .i32, .kind = .{ .reg = .edi } },113677 .{ .type = .i32, .kind = .{ .reg = .edi } },
113847 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsidf" } } },113678 .{ .type = .usize, .kind = .{ .extern_func = "__floatsidf" } },
113848 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },113679 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
113849 .unused,113680 .unused,
113850 .unused,113681 .unused,
...@@ -113875,7 +113706,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -113875,7 +113706,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
113875 .extra_temps = .{113706 .extra_temps = .{
113876 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },113707 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
113877 .{ .type = .i32, .kind = .{ .reg = .edi } },113708 .{ .type = .i32, .kind = .{ .reg = .edi } },
113878 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsidf" } } },113709 .{ .type = .usize, .kind = .{ .extern_func = "__floatsidf" } },
113879 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },113710 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
113880 .unused,113711 .unused,
113881 .unused,113712 .unused,
...@@ -113906,7 +113737,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -113906,7 +113737,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
113906 .extra_temps = .{113737 .extra_temps = .{
113907 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },113738 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
113908 .{ .type = .i32, .kind = .{ .reg = .edi } },113739 .{ .type = .i32, .kind = .{ .reg = .edi } },
113909 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsidf" } } },113740 .{ .type = .usize, .kind = .{ .extern_func = "__floatsidf" } },
113910 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },113741 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
113911 .unused,113742 .unused,
113912 .unused,113743 .unused,
...@@ -113937,7 +113768,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -113937,7 +113768,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
113937 .extra_temps = .{113768 .extra_temps = .{
113938 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },113769 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
113939 .{ .type = .i32, .kind = .{ .reg = .edi } },113770 .{ .type = .i32, .kind = .{ .reg = .edi } },
113940 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsidf" } } },113771 .{ .type = .usize, .kind = .{ .extern_func = "__floatsidf" } },
113941 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },113772 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
113942 .unused,113773 .unused,
113943 .unused,113774 .unused,
...@@ -113968,7 +113799,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -113968,7 +113799,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
113968 .extra_temps = .{113799 .extra_temps = .{
113969 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },113800 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
113970 .{ .type = .i32, .kind = .{ .reg = .edi } },113801 .{ .type = .i32, .kind = .{ .reg = .edi } },
113971 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsidf" } } },113802 .{ .type = .usize, .kind = .{ .extern_func = "__floatsidf" } },
113972 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },113803 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
113973 .unused,113804 .unused,
113974 .unused,113805 .unused,
...@@ -113999,7 +113830,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -113999,7 +113830,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
113999 .extra_temps = .{113830 .extra_temps = .{
114000 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },113831 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114001 .{ .type = .i32, .kind = .{ .reg = .edi } },113832 .{ .type = .i32, .kind = .{ .reg = .edi } },
114002 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsidf" } } },113833 .{ .type = .usize, .kind = .{ .extern_func = "__floatsidf" } },
114003 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },113834 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114004 .unused,113835 .unused,
114005 .unused,113836 .unused,
...@@ -114030,7 +113861,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114030,7 +113861,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114030 .extra_temps = .{113861 .extra_temps = .{
114031 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },113862 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114032 .{ .type = .u32, .kind = .{ .reg = .edi } },113863 .{ .type = .u32, .kind = .{ .reg = .edi } },
114033 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsidf" } } },113864 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsidf" } },
114034 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },113865 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114035 .unused,113866 .unused,
114036 .unused,113867 .unused,
...@@ -114061,7 +113892,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114061,7 +113892,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114061 .extra_temps = .{113892 .extra_temps = .{
114062 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },113893 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114063 .{ .type = .u32, .kind = .{ .reg = .edi } },113894 .{ .type = .u32, .kind = .{ .reg = .edi } },
114064 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsidf" } } },113895 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsidf" } },
114065 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },113896 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114066 .unused,113897 .unused,
114067 .unused,113898 .unused,
...@@ -114092,7 +113923,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114092,7 +113923,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114092 .extra_temps = .{113923 .extra_temps = .{
114093 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },113924 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114094 .{ .type = .u32, .kind = .{ .reg = .edi } },113925 .{ .type = .u32, .kind = .{ .reg = .edi } },
114095 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsidf" } } },113926 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsidf" } },
114096 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },113927 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114097 .unused,113928 .unused,
114098 .unused,113929 .unused,
...@@ -114123,7 +113954,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114123,7 +113954,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114123 .extra_temps = .{113954 .extra_temps = .{
114124 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },113955 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114125 .{ .type = .u32, .kind = .{ .reg = .edi } },113956 .{ .type = .u32, .kind = .{ .reg = .edi } },
114126 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsidf" } } },113957 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsidf" } },
114127 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },113958 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114128 .unused,113959 .unused,
114129 .unused,113960 .unused,
...@@ -114154,7 +113985,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114154,7 +113985,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114154 .extra_temps = .{113985 .extra_temps = .{
114155 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },113986 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114156 .{ .type = .u32, .kind = .{ .reg = .edi } },113987 .{ .type = .u32, .kind = .{ .reg = .edi } },
114157 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsidf" } } },113988 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsidf" } },
114158 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },113989 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114159 .unused,113990 .unused,
114160 .unused,113991 .unused,
...@@ -114185,7 +114016,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114185,7 +114016,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114185 .extra_temps = .{114016 .extra_temps = .{
114186 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114017 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114187 .{ .type = .u32, .kind = .{ .reg = .edi } },114018 .{ .type = .u32, .kind = .{ .reg = .edi } },
114188 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsidf" } } },114019 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsidf" } },
114189 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114020 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114190 .unused,114021 .unused,
114191 .unused,114022 .unused,
...@@ -114478,7 +114309,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114478,7 +114309,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114478 .extra_temps = .{114309 .extra_temps = .{
114479 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114310 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114480 .{ .type = .i32, .kind = .{ .reg = .edi } },114311 .{ .type = .i32, .kind = .{ .reg = .edi } },
114481 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsidf" } } },114312 .{ .type = .usize, .kind = .{ .extern_func = "__floatsidf" } },
114482 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114313 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114483 .unused,114314 .unused,
114484 .unused,114315 .unused,
...@@ -114509,7 +114340,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114509,7 +114340,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114509 .extra_temps = .{114340 .extra_temps = .{
114510 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114341 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114511 .{ .type = .i32, .kind = .{ .reg = .edi } },114342 .{ .type = .i32, .kind = .{ .reg = .edi } },
114512 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsidf" } } },114343 .{ .type = .usize, .kind = .{ .extern_func = "__floatsidf" } },
114513 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114344 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114514 .unused,114345 .unused,
114515 .unused,114346 .unused,
...@@ -114540,7 +114371,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114540,7 +114371,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114540 .extra_temps = .{114371 .extra_temps = .{
114541 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114372 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114542 .{ .type = .i32, .kind = .{ .reg = .edi } },114373 .{ .type = .i32, .kind = .{ .reg = .edi } },
114543 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsidf" } } },114374 .{ .type = .usize, .kind = .{ .extern_func = "__floatsidf" } },
114544 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114375 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114545 .unused,114376 .unused,
114546 .unused,114377 .unused,
...@@ -114571,7 +114402,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114571,7 +114402,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114571 .extra_temps = .{114402 .extra_temps = .{
114572 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114403 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114573 .{ .type = .u32, .kind = .{ .reg = .edi } },114404 .{ .type = .u32, .kind = .{ .reg = .edi } },
114574 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsidf" } } },114405 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsidf" } },
114575 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114406 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114576 .unused,114407 .unused,
114577 .unused,114408 .unused,
...@@ -114602,7 +114433,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114602,7 +114433,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114602 .extra_temps = .{114433 .extra_temps = .{
114603 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114434 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114604 .{ .type = .u32, .kind = .{ .reg = .edi } },114435 .{ .type = .u32, .kind = .{ .reg = .edi } },
114605 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsidf" } } },114436 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsidf" } },
114606 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114437 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114607 .unused,114438 .unused,
114608 .unused,114439 .unused,
...@@ -114633,7 +114464,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114633,7 +114464,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114633 .extra_temps = .{114464 .extra_temps = .{
114634 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114465 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114635 .{ .type = .u32, .kind = .{ .reg = .edi } },114466 .{ .type = .u32, .kind = .{ .reg = .edi } },
114636 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsidf" } } },114467 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsidf" } },
114637 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114468 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114638 .unused,114469 .unused,
114639 .unused,114470 .unused,
...@@ -114787,7 +114618,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114787,7 +114618,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114787 .extra_temps = .{114618 .extra_temps = .{
114788 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114619 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114789 .{ .type = .i32, .kind = .{ .reg = .edi } },114620 .{ .type = .i32, .kind = .{ .reg = .edi } },
114790 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsidf" } } },114621 .{ .type = .usize, .kind = .{ .extern_func = "__floatsidf" } },
114791 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114622 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114792 .unused,114623 .unused,
114793 .unused,114624 .unused,
...@@ -114818,7 +114649,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114818,7 +114649,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114818 .extra_temps = .{114649 .extra_temps = .{
114819 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114650 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114820 .{ .type = .i32, .kind = .{ .reg = .edi } },114651 .{ .type = .i32, .kind = .{ .reg = .edi } },
114821 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsidf" } } },114652 .{ .type = .usize, .kind = .{ .extern_func = "__floatsidf" } },
114822 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114653 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114823 .unused,114654 .unused,
114824 .unused,114655 .unused,
...@@ -114849,7 +114680,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114849,7 +114680,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114849 .extra_temps = .{114680 .extra_temps = .{
114850 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114681 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114851 .{ .type = .i32, .kind = .{ .reg = .edi } },114682 .{ .type = .i32, .kind = .{ .reg = .edi } },
114852 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsidf" } } },114683 .{ .type = .usize, .kind = .{ .extern_func = "__floatsidf" } },
114853 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114684 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114854 .unused,114685 .unused,
114855 .unused,114686 .unused,
...@@ -114880,7 +114711,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114880,7 +114711,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114880 .extra_temps = .{114711 .extra_temps = .{
114881 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114712 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114882 .{ .type = .u32, .kind = .{ .reg = .edi } },114713 .{ .type = .u32, .kind = .{ .reg = .edi } },
114883 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsidf" } } },114714 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsidf" } },
114884 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114715 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114885 .unused,114716 .unused,
114886 .unused,114717 .unused,
...@@ -114911,7 +114742,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114911,7 +114742,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114911 .extra_temps = .{114742 .extra_temps = .{
114912 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114743 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114913 .{ .type = .u32, .kind = .{ .reg = .edi } },114744 .{ .type = .u32, .kind = .{ .reg = .edi } },
114914 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsidf" } } },114745 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsidf" } },
114915 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114746 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114916 .unused,114747 .unused,
114917 .unused,114748 .unused,
...@@ -114942,7 +114773,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -114942,7 +114773,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
114942 .extra_temps = .{114773 .extra_temps = .{
114943 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114774 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
114944 .{ .type = .u32, .kind = .{ .reg = .edi } },114775 .{ .type = .u32, .kind = .{ .reg = .edi } },
114945 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsidf" } } },114776 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsidf" } },
114946 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114777 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
114947 .unused,114778 .unused,
114948 .unused,114779 .unused,
...@@ -115033,7 +114864,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115033,7 +114864,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115033 .extra_temps = .{114864 .extra_temps = .{
115034 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114865 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115035 .{ .type = .i64, .kind = .{ .reg = .rdi } },114866 .{ .type = .i64, .kind = .{ .reg = .rdi } },
115036 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatdidf" } } },114867 .{ .type = .usize, .kind = .{ .extern_func = "__floatdidf" } },
115037 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114868 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115038 .unused,114869 .unused,
115039 .unused,114870 .unused,
...@@ -115064,7 +114895,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115064,7 +114895,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115064 .extra_temps = .{114895 .extra_temps = .{
115065 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114896 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115066 .{ .type = .i64, .kind = .{ .reg = .rdi } },114897 .{ .type = .i64, .kind = .{ .reg = .rdi } },
115067 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatdidf" } } },114898 .{ .type = .usize, .kind = .{ .extern_func = "__floatdidf" } },
115068 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114899 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115069 .unused,114900 .unused,
115070 .unused,114901 .unused,
...@@ -115095,7 +114926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115095,7 +114926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115095 .extra_temps = .{114926 .extra_temps = .{
115096 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114927 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115097 .{ .type = .i64, .kind = .{ .reg = .rdi } },114928 .{ .type = .i64, .kind = .{ .reg = .rdi } },
115098 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatdidf" } } },114929 .{ .type = .usize, .kind = .{ .extern_func = "__floatdidf" } },
115099 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114930 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115100 .unused,114931 .unused,
115101 .unused,114932 .unused,
...@@ -115126,7 +114957,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115126,7 +114957,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115126 .extra_temps = .{114957 .extra_temps = .{
115127 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114958 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115128 .{ .type = .u64, .kind = .{ .reg = .rdi } },114959 .{ .type = .u64, .kind = .{ .reg = .rdi } },
115129 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatundidf" } } },114960 .{ .type = .usize, .kind = .{ .extern_func = "__floatundidf" } },
115130 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114961 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115131 .unused,114962 .unused,
115132 .unused,114963 .unused,
...@@ -115157,7 +114988,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115157,7 +114988,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115157 .extra_temps = .{114988 .extra_temps = .{
115158 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },114989 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115159 .{ .type = .u64, .kind = .{ .reg = .rdi } },114990 .{ .type = .u64, .kind = .{ .reg = .rdi } },
115160 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatundidf" } } },114991 .{ .type = .usize, .kind = .{ .extern_func = "__floatundidf" } },
115161 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },114992 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115162 .unused,114993 .unused,
115163 .unused,114994 .unused,
...@@ -115188,7 +115019,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115188,7 +115019,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115188 .extra_temps = .{115019 .extra_temps = .{
115189 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115020 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115190 .{ .type = .u64, .kind = .{ .reg = .rdi } },115021 .{ .type = .u64, .kind = .{ .reg = .rdi } },
115191 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatundidf" } } },115022 .{ .type = .usize, .kind = .{ .extern_func = "__floatundidf" } },
115192 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },115023 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115193 .unused,115024 .unused,
115194 .unused,115025 .unused,
...@@ -115220,7 +115051,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115220,7 +115051,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115220 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115051 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115221 .{ .type = .u64, .kind = .{ .reg = .rdi } },115052 .{ .type = .u64, .kind = .{ .reg = .rdi } },
115222 .{ .type = .i64, .kind = .{ .reg = .rsi } },115053 .{ .type = .i64, .kind = .{ .reg = .rsi } },
115223 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattidf" } } },115054 .{ .type = .usize, .kind = .{ .extern_func = "__floattidf" } },
115224 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },115055 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115225 .unused,115056 .unused,
115226 .unused,115057 .unused,
...@@ -115252,7 +115083,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115252,7 +115083,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115252 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115083 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115253 .{ .type = .u64, .kind = .{ .reg = .rdi } },115084 .{ .type = .u64, .kind = .{ .reg = .rdi } },
115254 .{ .type = .i64, .kind = .{ .reg = .rsi } },115085 .{ .type = .i64, .kind = .{ .reg = .rsi } },
115255 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattidf" } } },115086 .{ .type = .usize, .kind = .{ .extern_func = "__floattidf" } },
115256 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },115087 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115257 .unused,115088 .unused,
115258 .unused,115089 .unused,
...@@ -115284,7 +115115,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115284,7 +115115,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115284 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115115 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115285 .{ .type = .u64, .kind = .{ .reg = .rdi } },115116 .{ .type = .u64, .kind = .{ .reg = .rdi } },
115286 .{ .type = .i64, .kind = .{ .reg = .rsi } },115117 .{ .type = .i64, .kind = .{ .reg = .rsi } },
115287 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattidf" } } },115118 .{ .type = .usize, .kind = .{ .extern_func = "__floattidf" } },
115288 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },115119 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115289 .unused,115120 .unused,
115290 .unused,115121 .unused,
...@@ -115316,7 +115147,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115316,7 +115147,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115316 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115147 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115317 .{ .type = .u64, .kind = .{ .reg = .rdi } },115148 .{ .type = .u64, .kind = .{ .reg = .rdi } },
115318 .{ .type = .u64, .kind = .{ .reg = .rsi } },115149 .{ .type = .u64, .kind = .{ .reg = .rsi } },
115319 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntidf" } } },115150 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntidf" } },
115320 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },115151 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115321 .unused,115152 .unused,
115322 .unused,115153 .unused,
...@@ -115348,7 +115179,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115348,7 +115179,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115348 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115179 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115349 .{ .type = .u64, .kind = .{ .reg = .rdi } },115180 .{ .type = .u64, .kind = .{ .reg = .rdi } },
115350 .{ .type = .u64, .kind = .{ .reg = .rsi } },115181 .{ .type = .u64, .kind = .{ .reg = .rsi } },
115351 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntidf" } } },115182 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntidf" } },
115352 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },115183 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115353 .unused,115184 .unused,
115354 .unused,115185 .unused,
...@@ -115380,7 +115211,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115380,7 +115211,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115380 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115211 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115381 .{ .type = .u64, .kind = .{ .reg = .rdi } },115212 .{ .type = .u64, .kind = .{ .reg = .rdi } },
115382 .{ .type = .u64, .kind = .{ .reg = .rsi } },115213 .{ .type = .u64, .kind = .{ .reg = .rsi } },
115383 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntidf" } } },115214 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntidf" } },
115384 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },115215 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115385 .unused,115216 .unused,
115386 .unused,115217 .unused,
...@@ -115413,7 +115244,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115413,7 +115244,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115413 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115244 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115414 .{ .type = .usize, .kind = .{ .reg = .rdi } },115245 .{ .type = .usize, .kind = .{ .reg = .rdi } },
115415 .{ .type = .usize, .kind = .{ .reg = .rsi } },115246 .{ .type = .usize, .kind = .{ .reg = .rsi } },
115416 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateidf" } } },115247 .{ .type = .usize, .kind = .{ .extern_func = "__floateidf" } },
115417 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },115248 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115418 .unused,115249 .unused,
115419 .unused,115250 .unused,
...@@ -115447,7 +115278,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115447,7 +115278,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115447 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115278 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115448 .{ .type = .usize, .kind = .{ .reg = .rdi } },115279 .{ .type = .usize, .kind = .{ .reg = .rdi } },
115449 .{ .type = .usize, .kind = .{ .reg = .rsi } },115280 .{ .type = .usize, .kind = .{ .reg = .rsi } },
115450 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateidf" } } },115281 .{ .type = .usize, .kind = .{ .extern_func = "__floateidf" } },
115451 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },115282 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115452 .unused,115283 .unused,
115453 .unused,115284 .unused,
...@@ -115481,7 +115312,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115481,7 +115312,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115481 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115312 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115482 .{ .type = .usize, .kind = .{ .reg = .rdi } },115313 .{ .type = .usize, .kind = .{ .reg = .rdi } },
115483 .{ .type = .usize, .kind = .{ .reg = .rsi } },115314 .{ .type = .usize, .kind = .{ .reg = .rsi } },
115484 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateidf" } } },115315 .{ .type = .usize, .kind = .{ .extern_func = "__floateidf" } },
115485 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },115316 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115486 .unused,115317 .unused,
115487 .unused,115318 .unused,
...@@ -115515,7 +115346,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115515,7 +115346,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115515 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115346 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115516 .{ .type = .usize, .kind = .{ .reg = .rdi } },115347 .{ .type = .usize, .kind = .{ .reg = .rdi } },
115517 .{ .type = .usize, .kind = .{ .reg = .rsi } },115348 .{ .type = .usize, .kind = .{ .reg = .rsi } },
115518 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneidf" } } },115349 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneidf" } },
115519 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },115350 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115520 .unused,115351 .unused,
115521 .unused,115352 .unused,
...@@ -115549,7 +115380,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115549,7 +115380,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115549 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115380 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115550 .{ .type = .usize, .kind = .{ .reg = .rdi } },115381 .{ .type = .usize, .kind = .{ .reg = .rdi } },
115551 .{ .type = .usize, .kind = .{ .reg = .rsi } },115382 .{ .type = .usize, .kind = .{ .reg = .rsi } },
115552 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneidf" } } },115383 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneidf" } },
115553 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },115384 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115554 .unused,115385 .unused,
115555 .unused,115386 .unused,
...@@ -115583,7 +115414,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115583,7 +115414,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115583 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115414 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
115584 .{ .type = .usize, .kind = .{ .reg = .rdi } },115415 .{ .type = .usize, .kind = .{ .reg = .rdi } },
115585 .{ .type = .usize, .kind = .{ .reg = .rsi } },115416 .{ .type = .usize, .kind = .{ .reg = .rsi } },
115586 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneidf" } } },115417 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneidf" } },
115587 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },115418 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
115588 .unused,115419 .unused,
115589 .unused,115420 .unused,
...@@ -115830,7 +115661,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115830,7 +115661,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115830 },115661 },
115831 .call_frame = .{ .alignment = .@"16" },115662 .call_frame = .{ .alignment = .@"16" },
115832 .extra_temps = .{115663 .extra_temps = .{
115833 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattixf" } } },115664 .{ .type = .usize, .kind = .{ .extern_func = "__floattixf" } },
115834 .unused,115665 .unused,
115835 .unused,115666 .unused,
115836 .unused,115667 .unused,
...@@ -115856,7 +115687,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115856,7 +115687,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115856 },115687 },
115857 .call_frame = .{ .alignment = .@"16" },115688 .call_frame = .{ .alignment = .@"16" },
115858 .extra_temps = .{115689 .extra_temps = .{
115859 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntixf" } } },115690 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntixf" } },
115860 .unused,115691 .unused,
115861 .unused,115692 .unused,
115862 .unused,115693 .unused,
...@@ -115884,7 +115715,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115884,7 +115715,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115884 .extra_temps = .{115715 .extra_temps = .{
115885 .{ .type = .usize, .kind = .{ .reg = .rdi } },115716 .{ .type = .usize, .kind = .{ .reg = .rdi } },
115886 .{ .type = .usize, .kind = .{ .reg = .rsi } },115717 .{ .type = .usize, .kind = .{ .reg = .rsi } },
115887 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateixf" } } },115718 .{ .type = .usize, .kind = .{ .extern_func = "__floateixf" } },
115888 .unused,115719 .unused,
115889 .unused,115720 .unused,
115890 .unused,115721 .unused,
...@@ -115912,7 +115743,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115912,7 +115743,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115912 .extra_temps = .{115743 .extra_temps = .{
115913 .{ .type = .usize, .kind = .{ .reg = .rdi } },115744 .{ .type = .usize, .kind = .{ .reg = .rdi } },
115914 .{ .type = .usize, .kind = .{ .reg = .rsi } },115745 .{ .type = .usize, .kind = .{ .reg = .rsi } },
115915 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneixf" } } },115746 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneixf" } },
115916 .unused,115747 .unused,
115917 .unused,115748 .unused,
115918 .unused,115749 .unused,
...@@ -116073,7 +115904,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116073,7 +115904,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116073 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115904 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116074 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },115905 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
116075 .{ .type = .i32, .kind = .{ .reg = .edi } },115906 .{ .type = .i32, .kind = .{ .reg = .edi } },
116076 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsixf" } } },115907 .{ .type = .usize, .kind = .{ .extern_func = "__floatsixf" } },
116077 .{ .type = .f80, .kind = .{ .reg = .st7 } },115908 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116078 .unused,115909 .unused,
116079 .unused,115910 .unused,
...@@ -116107,7 +115938,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116107,7 +115938,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116107 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115938 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116108 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },115939 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
116109 .{ .type = .i32, .kind = .{ .reg = .edi } },115940 .{ .type = .i32, .kind = .{ .reg = .edi } },
116110 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsixf" } } },115941 .{ .type = .usize, .kind = .{ .extern_func = "__floatsixf" } },
116111 .{ .type = .f80, .kind = .{ .reg = .st7 } },115942 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116112 .unused,115943 .unused,
116113 .unused,115944 .unused,
...@@ -116141,7 +115972,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116141,7 +115972,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116141 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },115972 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116142 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },115973 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
116143 .{ .type = .u32, .kind = .{ .reg = .edi } },115974 .{ .type = .u32, .kind = .{ .reg = .edi } },
116144 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsixf" } } },115975 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsixf" } },
116145 .{ .type = .f80, .kind = .{ .reg = .st7 } },115976 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116146 .unused,115977 .unused,
116147 .unused,115978 .unused,
...@@ -116175,7 +116006,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116175,7 +116006,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116175 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116006 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116176 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },116007 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
116177 .{ .type = .u32, .kind = .{ .reg = .edi } },116008 .{ .type = .u32, .kind = .{ .reg = .edi } },
116178 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsixf" } } },116009 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsixf" } },
116179 .{ .type = .f80, .kind = .{ .reg = .st7 } },116010 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116180 .unused,116011 .unused,
116181 .unused,116012 .unused,
...@@ -116237,7 +116068,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116237,7 +116068,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116237 .extra_temps = .{116068 .extra_temps = .{
116238 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116069 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116239 .{ .type = .i32, .kind = .{ .reg = .edi } },116070 .{ .type = .i32, .kind = .{ .reg = .edi } },
116240 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsixf" } } },116071 .{ .type = .usize, .kind = .{ .extern_func = "__floatsixf" } },
116241 .{ .type = .f80, .kind = .{ .reg = .st7 } },116072 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116242 .unused,116073 .unused,
116243 .unused,116074 .unused,
...@@ -116269,7 +116100,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116269,7 +116100,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116269 .extra_temps = .{116100 .extra_temps = .{
116270 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116101 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116271 .{ .type = .u32, .kind = .{ .reg = .edi } },116102 .{ .type = .u32, .kind = .{ .reg = .edi } },
116272 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsixf" } } },116103 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsixf" } },
116273 .{ .type = .f80, .kind = .{ .reg = .st7 } },116104 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116274 .unused,116105 .unused,
116275 .unused,116106 .unused,
...@@ -116330,7 +116161,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116330,7 +116161,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116330 .extra_temps = .{116161 .extra_temps = .{
116331 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116162 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116332 .{ .type = .i32, .kind = .{ .reg = .edi } },116163 .{ .type = .i32, .kind = .{ .reg = .edi } },
116333 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsixf" } } },116164 .{ .type = .usize, .kind = .{ .extern_func = "__floatsixf" } },
116334 .{ .type = .f80, .kind = .{ .reg = .st7 } },116165 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116335 .unused,116166 .unused,
116336 .unused,116167 .unused,
...@@ -116362,7 +116193,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116362,7 +116193,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116362 .extra_temps = .{116193 .extra_temps = .{
116363 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116194 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116364 .{ .type = .u32, .kind = .{ .reg = .edi } },116195 .{ .type = .u32, .kind = .{ .reg = .edi } },
116365 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsixf" } } },116196 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsixf" } },
116366 .{ .type = .f80, .kind = .{ .reg = .st7 } },116197 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116367 .unused,116198 .unused,
116368 .unused,116199 .unused,
...@@ -116423,7 +116254,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116423,7 +116254,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116423 .extra_temps = .{116254 .extra_temps = .{
116424 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116255 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116425 .{ .type = .i64, .kind = .{ .reg = .rdi } },116256 .{ .type = .i64, .kind = .{ .reg = .rdi } },
116426 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatdixf" } } },116257 .{ .type = .usize, .kind = .{ .extern_func = "__floatdixf" } },
116427 .{ .type = .f80, .kind = .{ .reg = .st7 } },116258 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116428 .unused,116259 .unused,
116429 .unused,116260 .unused,
...@@ -116455,7 +116286,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116455,7 +116286,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116455 .extra_temps = .{116286 .extra_temps = .{
116456 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116287 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116457 .{ .type = .u64, .kind = .{ .reg = .rdi } },116288 .{ .type = .u64, .kind = .{ .reg = .rdi } },
116458 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatundixf" } } },116289 .{ .type = .usize, .kind = .{ .extern_func = "__floatundixf" } },
116459 .{ .type = .f80, .kind = .{ .reg = .st7 } },116290 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116460 .unused,116291 .unused,
116461 .unused,116292 .unused,
...@@ -116488,7 +116319,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116488,7 +116319,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116488 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116319 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116489 .{ .type = .u64, .kind = .{ .reg = .rdi } },116320 .{ .type = .u64, .kind = .{ .reg = .rdi } },
116490 .{ .type = .i64, .kind = .{ .reg = .rsi } },116321 .{ .type = .i64, .kind = .{ .reg = .rsi } },
116491 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattixf" } } },116322 .{ .type = .usize, .kind = .{ .extern_func = "__floattixf" } },
116492 .{ .type = .f80, .kind = .{ .reg = .st7 } },116323 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116493 .unused,116324 .unused,
116494 .unused,116325 .unused,
...@@ -116521,7 +116352,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116521,7 +116352,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116521 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116352 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116522 .{ .type = .u64, .kind = .{ .reg = .rdi } },116353 .{ .type = .u64, .kind = .{ .reg = .rdi } },
116523 .{ .type = .u64, .kind = .{ .reg = .rsi } },116354 .{ .type = .u64, .kind = .{ .reg = .rsi } },
116524 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntixf" } } },116355 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntixf" } },
116525 .{ .type = .f80, .kind = .{ .reg = .st7 } },116356 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116526 .unused,116357 .unused,
116527 .unused,116358 .unused,
...@@ -116555,7 +116386,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116555,7 +116386,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116555 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116386 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116556 .{ .type = .usize, .kind = .{ .reg = .rdi } },116387 .{ .type = .usize, .kind = .{ .reg = .rdi } },
116557 .{ .type = .usize, .kind = .{ .reg = .rsi } },116388 .{ .type = .usize, .kind = .{ .reg = .rsi } },
116558 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateixf" } } },116389 .{ .type = .usize, .kind = .{ .extern_func = "__floateixf" } },
116559 .{ .type = .f80, .kind = .{ .reg = .st7 } },116390 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116560 .unused,116391 .unused,
116561 .unused,116392 .unused,
...@@ -116590,7 +116421,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116590,7 +116421,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116590 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116421 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116591 .{ .type = .usize, .kind = .{ .reg = .rdi } },116422 .{ .type = .usize, .kind = .{ .reg = .rdi } },
116592 .{ .type = .usize, .kind = .{ .reg = .rsi } },116423 .{ .type = .usize, .kind = .{ .reg = .rsi } },
116593 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneixf" } } },116424 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneixf" } },
116594 .{ .type = .f80, .kind = .{ .reg = .st7 } },116425 .{ .type = .f80, .kind = .{ .reg = .st7 } },
116595 .unused,116426 .unused,
116596 .unused,116427 .unused,
...@@ -116623,7 +116454,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116623,7 +116454,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116623 .call_frame = .{ .alignment = .@"16" },116454 .call_frame = .{ .alignment = .@"16" },
116624 .extra_temps = .{116455 .extra_temps = .{
116625 .{ .type = .i32, .kind = .{ .reg = .edi } },116456 .{ .type = .i32, .kind = .{ .reg = .edi } },
116626 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },116457 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
116627 .unused,116458 .unused,
116628 .unused,116459 .unused,
116629 .unused,116460 .unused,
...@@ -116651,7 +116482,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116651,7 +116482,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116651 .call_frame = .{ .alignment = .@"16" },116482 .call_frame = .{ .alignment = .@"16" },
116652 .extra_temps = .{116483 .extra_temps = .{
116653 .{ .type = .u32, .kind = .{ .reg = .edi } },116484 .{ .type = .u32, .kind = .{ .reg = .edi } },
116654 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },116485 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
116655 .unused,116486 .unused,
116656 .unused,116487 .unused,
116657 .unused,116488 .unused,
...@@ -116679,7 +116510,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116679,7 +116510,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116679 .call_frame = .{ .alignment = .@"16" },116510 .call_frame = .{ .alignment = .@"16" },
116680 .extra_temps = .{116511 .extra_temps = .{
116681 .{ .type = .i32, .kind = .{ .reg = .edi } },116512 .{ .type = .i32, .kind = .{ .reg = .edi } },
116682 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },116513 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
116683 .unused,116514 .unused,
116684 .unused,116515 .unused,
116685 .unused,116516 .unused,
...@@ -116707,7 +116538,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116707,7 +116538,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116707 .call_frame = .{ .alignment = .@"16" },116538 .call_frame = .{ .alignment = .@"16" },
116708 .extra_temps = .{116539 .extra_temps = .{
116709 .{ .type = .u32, .kind = .{ .reg = .edi } },116540 .{ .type = .u32, .kind = .{ .reg = .edi } },
116710 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },116541 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
116711 .unused,116542 .unused,
116712 .unused,116543 .unused,
116713 .unused,116544 .unused,
...@@ -116733,7 +116564,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116733,7 +116564,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116733 },116564 },
116734 .call_frame = .{ .alignment = .@"16" },116565 .call_frame = .{ .alignment = .@"16" },
116735 .extra_temps = .{116566 .extra_temps = .{
116736 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },116567 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
116737 .unused,116568 .unused,
116738 .unused,116569 .unused,
116739 .unused,116570 .unused,
...@@ -116759,7 +116590,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116759,7 +116590,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116759 },116590 },
116760 .call_frame = .{ .alignment = .@"16" },116591 .call_frame = .{ .alignment = .@"16" },
116761 .extra_temps = .{116592 .extra_temps = .{
116762 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },116593 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
116763 .unused,116594 .unused,
116764 .unused,116595 .unused,
116765 .unused,116596 .unused,
...@@ -116785,7 +116616,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116785,7 +116616,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116785 },116616 },
116786 .call_frame = .{ .alignment = .@"16" },116617 .call_frame = .{ .alignment = .@"16" },
116787 .extra_temps = .{116618 .extra_temps = .{
116788 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatditf" } } },116619 .{ .type = .usize, .kind = .{ .extern_func = "__floatditf" } },
116789 .unused,116620 .unused,
116790 .unused,116621 .unused,
116791 .unused,116622 .unused,
...@@ -116811,7 +116642,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116811,7 +116642,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116811 },116642 },
116812 .call_frame = .{ .alignment = .@"16" },116643 .call_frame = .{ .alignment = .@"16" },
116813 .extra_temps = .{116644 .extra_temps = .{
116814 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunditf" } } },116645 .{ .type = .usize, .kind = .{ .extern_func = "__floatunditf" } },
116815 .unused,116646 .unused,
116816 .unused,116647 .unused,
116817 .unused,116648 .unused,
...@@ -116837,7 +116668,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116837,7 +116668,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116837 },116668 },
116838 .call_frame = .{ .alignment = .@"16" },116669 .call_frame = .{ .alignment = .@"16" },
116839 .extra_temps = .{116670 .extra_temps = .{
116840 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattitf" } } },116671 .{ .type = .usize, .kind = .{ .extern_func = "__floattitf" } },
116841 .unused,116672 .unused,
116842 .unused,116673 .unused,
116843 .unused,116674 .unused,
...@@ -116863,7 +116694,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116863,7 +116694,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116863 },116694 },
116864 .call_frame = .{ .alignment = .@"16" },116695 .call_frame = .{ .alignment = .@"16" },
116865 .extra_temps = .{116696 .extra_temps = .{
116866 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntitf" } } },116697 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntitf" } },
116867 .unused,116698 .unused,
116868 .unused,116699 .unused,
116869 .unused,116700 .unused,
...@@ -116891,7 +116722,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116891,7 +116722,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116891 .extra_temps = .{116722 .extra_temps = .{
116892 .{ .type = .usize, .kind = .{ .reg = .rdi } },116723 .{ .type = .usize, .kind = .{ .reg = .rdi } },
116893 .{ .type = .usize, .kind = .{ .reg = .rsi } },116724 .{ .type = .usize, .kind = .{ .reg = .rsi } },
116894 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateitf" } } },116725 .{ .type = .usize, .kind = .{ .extern_func = "__floateitf" } },
116895 .unused,116726 .unused,
116896 .unused,116727 .unused,
116897 .unused,116728 .unused,
...@@ -116919,7 +116750,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116919,7 +116750,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116919 .extra_temps = .{116750 .extra_temps = .{
116920 .{ .type = .usize, .kind = .{ .reg = .rdi } },116751 .{ .type = .usize, .kind = .{ .reg = .rdi } },
116921 .{ .type = .usize, .kind = .{ .reg = .rsi } },116752 .{ .type = .usize, .kind = .{ .reg = .rsi } },
116922 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneitf" } } },116753 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneitf" } },
116923 .unused,116754 .unused,
116924 .unused,116755 .unused,
116925 .unused,116756 .unused,
...@@ -116948,7 +116779,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116948,7 +116779,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116948 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116779 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116949 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },116780 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
116950 .{ .type = .i32, .kind = .{ .reg = .edi } },116781 .{ .type = .i32, .kind = .{ .reg = .edi } },
116951 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },116782 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
116952 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },116783 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
116953 .unused,116784 .unused,
116954 .unused,116785 .unused,
...@@ -116981,7 +116812,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -116981,7 +116812,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
116981 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116812 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
116982 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },116813 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
116983 .{ .type = .i32, .kind = .{ .reg = .edi } },116814 .{ .type = .i32, .kind = .{ .reg = .edi } },
116984 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },116815 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
116985 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },116816 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
116986 .unused,116817 .unused,
116987 .unused,116818 .unused,
...@@ -117014,7 +116845,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117014,7 +116845,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117014 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116845 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117015 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },116846 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
117016 .{ .type = .i32, .kind = .{ .reg = .edi } },116847 .{ .type = .i32, .kind = .{ .reg = .edi } },
117017 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },116848 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
117018 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },116849 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117019 .unused,116850 .unused,
117020 .unused,116851 .unused,
...@@ -117047,7 +116878,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117047,7 +116878,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117047 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116878 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117048 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },116879 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
117049 .{ .type = .i32, .kind = .{ .reg = .edi } },116880 .{ .type = .i32, .kind = .{ .reg = .edi } },
117050 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },116881 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
117051 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },116882 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117052 .unused,116883 .unused,
117053 .unused,116884 .unused,
...@@ -117080,7 +116911,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117080,7 +116911,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117080 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116911 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117081 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },116912 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
117082 .{ .type = .i32, .kind = .{ .reg = .edi } },116913 .{ .type = .i32, .kind = .{ .reg = .edi } },
117083 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },116914 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
117084 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },116915 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117085 .unused,116916 .unused,
117086 .unused,116917 .unused,
...@@ -117113,7 +116944,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117113,7 +116944,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117113 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116944 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117114 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },116945 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
117115 .{ .type = .i32, .kind = .{ .reg = .edi } },116946 .{ .type = .i32, .kind = .{ .reg = .edi } },
117116 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },116947 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
117117 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },116948 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117118 .unused,116949 .unused,
117119 .unused,116950 .unused,
...@@ -117146,7 +116977,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117146,7 +116977,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117146 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },116977 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117147 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },116978 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
117148 .{ .type = .u32, .kind = .{ .reg = .edi } },116979 .{ .type = .u32, .kind = .{ .reg = .edi } },
117149 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },116980 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
117150 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },116981 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117151 .unused,116982 .unused,
117152 .unused,116983 .unused,
...@@ -117179,7 +117010,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117179,7 +117010,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117179 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117010 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117180 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },117011 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
117181 .{ .type = .u32, .kind = .{ .reg = .edi } },117012 .{ .type = .u32, .kind = .{ .reg = .edi } },
117182 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },117013 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
117183 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117014 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117184 .unused,117015 .unused,
117185 .unused,117016 .unused,
...@@ -117212,7 +117043,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117212,7 +117043,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117212 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117043 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117213 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },117044 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
117214 .{ .type = .u32, .kind = .{ .reg = .edi } },117045 .{ .type = .u32, .kind = .{ .reg = .edi } },
117215 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },117046 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
117216 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117047 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117217 .unused,117048 .unused,
117218 .unused,117049 .unused,
...@@ -117245,7 +117076,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117245,7 +117076,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117245 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117076 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117246 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },117077 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
117247 .{ .type = .u32, .kind = .{ .reg = .edi } },117078 .{ .type = .u32, .kind = .{ .reg = .edi } },
117248 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },117079 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
117249 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117080 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117250 .unused,117081 .unused,
117251 .unused,117082 .unused,
...@@ -117278,7 +117109,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117278,7 +117109,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117278 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117109 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117279 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },117110 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
117280 .{ .type = .u32, .kind = .{ .reg = .edi } },117111 .{ .type = .u32, .kind = .{ .reg = .edi } },
117281 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },117112 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
117282 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117113 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117283 .unused,117114 .unused,
117284 .unused,117115 .unused,
...@@ -117311,7 +117142,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117311,7 +117142,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117311 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117142 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117312 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },117143 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
117313 .{ .type = .u32, .kind = .{ .reg = .edi } },117144 .{ .type = .u32, .kind = .{ .reg = .edi } },
117314 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },117145 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
117315 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117146 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117316 .unused,117147 .unused,
117317 .unused,117148 .unused,
...@@ -117343,7 +117174,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117343,7 +117174,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117343 .extra_temps = .{117174 .extra_temps = .{
117344 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117175 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117345 .{ .type = .i32, .kind = .{ .reg = .edi } },117176 .{ .type = .i32, .kind = .{ .reg = .edi } },
117346 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },117177 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
117347 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117178 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117348 .unused,117179 .unused,
117349 .unused,117180 .unused,
...@@ -117374,7 +117205,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117374,7 +117205,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117374 .extra_temps = .{117205 .extra_temps = .{
117375 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117206 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117376 .{ .type = .i32, .kind = .{ .reg = .edi } },117207 .{ .type = .i32, .kind = .{ .reg = .edi } },
117377 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },117208 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
117378 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117209 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117379 .unused,117210 .unused,
117380 .unused,117211 .unused,
...@@ -117405,7 +117236,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117405,7 +117236,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117405 .extra_temps = .{117236 .extra_temps = .{
117406 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117237 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117407 .{ .type = .i32, .kind = .{ .reg = .edi } },117238 .{ .type = .i32, .kind = .{ .reg = .edi } },
117408 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },117239 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
117409 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117240 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117410 .unused,117241 .unused,
117411 .unused,117242 .unused,
...@@ -117436,7 +117267,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117436,7 +117267,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117436 .extra_temps = .{117267 .extra_temps = .{
117437 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117268 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117438 .{ .type = .u32, .kind = .{ .reg = .edi } },117269 .{ .type = .u32, .kind = .{ .reg = .edi } },
117439 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },117270 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
117440 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117271 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117441 .unused,117272 .unused,
117442 .unused,117273 .unused,
...@@ -117467,7 +117298,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117467,7 +117298,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117467 .extra_temps = .{117298 .extra_temps = .{
117468 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117299 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117469 .{ .type = .u32, .kind = .{ .reg = .edi } },117300 .{ .type = .u32, .kind = .{ .reg = .edi } },
117470 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },117301 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
117471 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117302 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117472 .unused,117303 .unused,
117473 .unused,117304 .unused,
...@@ -117498,7 +117329,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117498,7 +117329,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117498 .extra_temps = .{117329 .extra_temps = .{
117499 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117330 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117500 .{ .type = .u32, .kind = .{ .reg = .edi } },117331 .{ .type = .u32, .kind = .{ .reg = .edi } },
117501 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },117332 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
117502 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117333 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117503 .unused,117334 .unused,
117504 .unused,117335 .unused,
...@@ -117529,7 +117360,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117529,7 +117360,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117529 .extra_temps = .{117360 .extra_temps = .{
117530 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117361 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117531 .{ .type = .i32, .kind = .{ .reg = .edi } },117362 .{ .type = .i32, .kind = .{ .reg = .edi } },
117532 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },117363 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
117533 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117364 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117534 .unused,117365 .unused,
117535 .unused,117366 .unused,
...@@ -117560,7 +117391,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117560,7 +117391,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117560 .extra_temps = .{117391 .extra_temps = .{
117561 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117392 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117562 .{ .type = .i32, .kind = .{ .reg = .edi } },117393 .{ .type = .i32, .kind = .{ .reg = .edi } },
117563 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },117394 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
117564 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117395 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117565 .unused,117396 .unused,
117566 .unused,117397 .unused,
...@@ -117591,7 +117422,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117591,7 +117422,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117591 .extra_temps = .{117422 .extra_temps = .{
117592 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117423 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117593 .{ .type = .i32, .kind = .{ .reg = .edi } },117424 .{ .type = .i32, .kind = .{ .reg = .edi } },
117594 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatsitf" } } },117425 .{ .type = .usize, .kind = .{ .extern_func = "__floatsitf" } },
117595 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117426 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117596 .unused,117427 .unused,
117597 .unused,117428 .unused,
...@@ -117622,7 +117453,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117622,7 +117453,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117622 .extra_temps = .{117453 .extra_temps = .{
117623 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117454 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117624 .{ .type = .u32, .kind = .{ .reg = .edi } },117455 .{ .type = .u32, .kind = .{ .reg = .edi } },
117625 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },117456 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
117626 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117457 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117627 .unused,117458 .unused,
117628 .unused,117459 .unused,
...@@ -117653,7 +117484,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117653,7 +117484,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117653 .extra_temps = .{117484 .extra_temps = .{
117654 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117485 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117655 .{ .type = .u32, .kind = .{ .reg = .edi } },117486 .{ .type = .u32, .kind = .{ .reg = .edi } },
117656 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },117487 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
117657 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117488 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117658 .unused,117489 .unused,
117659 .unused,117490 .unused,
...@@ -117684,7 +117515,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117684,7 +117515,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117684 .extra_temps = .{117515 .extra_temps = .{
117685 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117516 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117686 .{ .type = .u32, .kind = .{ .reg = .edi } },117517 .{ .type = .u32, .kind = .{ .reg = .edi } },
117687 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunsitf" } } },117518 .{ .type = .usize, .kind = .{ .extern_func = "__floatunsitf" } },
117688 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117519 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117689 .unused,117520 .unused,
117690 .unused,117521 .unused,
...@@ -117715,7 +117546,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117715,7 +117546,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117715 .extra_temps = .{117546 .extra_temps = .{
117716 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117547 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117717 .{ .type = .i64, .kind = .{ .reg = .rdi } },117548 .{ .type = .i64, .kind = .{ .reg = .rdi } },
117718 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatditf" } } },117549 .{ .type = .usize, .kind = .{ .extern_func = "__floatditf" } },
117719 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117550 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117720 .unused,117551 .unused,
117721 .unused,117552 .unused,
...@@ -117746,7 +117577,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117746,7 +117577,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117746 .extra_temps = .{117577 .extra_temps = .{
117747 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117578 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117748 .{ .type = .i64, .kind = .{ .reg = .rdi } },117579 .{ .type = .i64, .kind = .{ .reg = .rdi } },
117749 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatditf" } } },117580 .{ .type = .usize, .kind = .{ .extern_func = "__floatditf" } },
117750 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117581 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117751 .unused,117582 .unused,
117752 .unused,117583 .unused,
...@@ -117777,7 +117608,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117777,7 +117608,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117777 .extra_temps = .{117608 .extra_temps = .{
117778 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117609 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117779 .{ .type = .i64, .kind = .{ .reg = .rdi } },117610 .{ .type = .i64, .kind = .{ .reg = .rdi } },
117780 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatditf" } } },117611 .{ .type = .usize, .kind = .{ .extern_func = "__floatditf" } },
117781 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117612 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117782 .unused,117613 .unused,
117783 .unused,117614 .unused,
...@@ -117808,7 +117639,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117808,7 +117639,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117808 .extra_temps = .{117639 .extra_temps = .{
117809 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117640 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117810 .{ .type = .u64, .kind = .{ .reg = .rdi } },117641 .{ .type = .u64, .kind = .{ .reg = .rdi } },
117811 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunditf" } } },117642 .{ .type = .usize, .kind = .{ .extern_func = "__floatunditf" } },
117812 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117643 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117813 .unused,117644 .unused,
117814 .unused,117645 .unused,
...@@ -117839,7 +117670,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117839,7 +117670,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117839 .extra_temps = .{117670 .extra_temps = .{
117840 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117671 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117841 .{ .type = .u64, .kind = .{ .reg = .rdi } },117672 .{ .type = .u64, .kind = .{ .reg = .rdi } },
117842 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunditf" } } },117673 .{ .type = .usize, .kind = .{ .extern_func = "__floatunditf" } },
117843 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117674 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117844 .unused,117675 .unused,
117845 .unused,117676 .unused,
...@@ -117870,7 +117701,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117870,7 +117701,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117870 .extra_temps = .{117701 .extra_temps = .{
117871 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117702 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117872 .{ .type = .u64, .kind = .{ .reg = .rdi } },117703 .{ .type = .u64, .kind = .{ .reg = .rdi } },
117873 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatunditf" } } },117704 .{ .type = .usize, .kind = .{ .extern_func = "__floatunditf" } },
117874 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117705 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117875 .unused,117706 .unused,
117876 .unused,117707 .unused,
...@@ -117902,7 +117733,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117902,7 +117733,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117902 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117733 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117903 .{ .type = .u64, .kind = .{ .reg = .rdi } },117734 .{ .type = .u64, .kind = .{ .reg = .rdi } },
117904 .{ .type = .i64, .kind = .{ .reg = .rsi } },117735 .{ .type = .i64, .kind = .{ .reg = .rsi } },
117905 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattitf" } } },117736 .{ .type = .usize, .kind = .{ .extern_func = "__floattitf" } },
117906 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117737 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117907 .unused,117738 .unused,
117908 .unused,117739 .unused,
...@@ -117934,7 +117765,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117934,7 +117765,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117934 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117765 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117935 .{ .type = .u64, .kind = .{ .reg = .rdi } },117766 .{ .type = .u64, .kind = .{ .reg = .rdi } },
117936 .{ .type = .i64, .kind = .{ .reg = .rsi } },117767 .{ .type = .i64, .kind = .{ .reg = .rsi } },
117937 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattitf" } } },117768 .{ .type = .usize, .kind = .{ .extern_func = "__floattitf" } },
117938 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117769 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117939 .unused,117770 .unused,
117940 .unused,117771 .unused,
...@@ -117966,7 +117797,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117966,7 +117797,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117966 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117797 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117967 .{ .type = .u64, .kind = .{ .reg = .rdi } },117798 .{ .type = .u64, .kind = .{ .reg = .rdi } },
117968 .{ .type = .i64, .kind = .{ .reg = .rsi } },117799 .{ .type = .i64, .kind = .{ .reg = .rsi } },
117969 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floattitf" } } },117800 .{ .type = .usize, .kind = .{ .extern_func = "__floattitf" } },
117970 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117801 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
117971 .unused,117802 .unused,
117972 .unused,117803 .unused,
...@@ -117998,7 +117829,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -117998,7 +117829,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
117998 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117829 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
117999 .{ .type = .u64, .kind = .{ .reg = .rdi } },117830 .{ .type = .u64, .kind = .{ .reg = .rdi } },
118000 .{ .type = .u64, .kind = .{ .reg = .rsi } },117831 .{ .type = .u64, .kind = .{ .reg = .rsi } },
118001 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntitf" } } },117832 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntitf" } },
118002 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117833 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
118003 .unused,117834 .unused,
118004 .unused,117835 .unused,
...@@ -118030,7 +117861,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -118030,7 +117861,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
118030 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117861 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
118031 .{ .type = .u64, .kind = .{ .reg = .rdi } },117862 .{ .type = .u64, .kind = .{ .reg = .rdi } },
118032 .{ .type = .u64, .kind = .{ .reg = .rsi } },117863 .{ .type = .u64, .kind = .{ .reg = .rsi } },
118033 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntitf" } } },117864 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntitf" } },
118034 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117865 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
118035 .unused,117866 .unused,
118036 .unused,117867 .unused,
...@@ -118062,7 +117893,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -118062,7 +117893,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
118062 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117893 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
118063 .{ .type = .u64, .kind = .{ .reg = .rdi } },117894 .{ .type = .u64, .kind = .{ .reg = .rdi } },
118064 .{ .type = .u64, .kind = .{ .reg = .rsi } },117895 .{ .type = .u64, .kind = .{ .reg = .rsi } },
118065 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuntitf" } } },117896 .{ .type = .usize, .kind = .{ .extern_func = "__floatuntitf" } },
118066 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117897 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
118067 .unused,117898 .unused,
118068 .unused,117899 .unused,
...@@ -118095,7 +117926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -118095,7 +117926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
118095 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117926 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
118096 .{ .type = .usize, .kind = .{ .reg = .rdi } },117927 .{ .type = .usize, .kind = .{ .reg = .rdi } },
118097 .{ .type = .usize, .kind = .{ .reg = .rsi } },117928 .{ .type = .usize, .kind = .{ .reg = .rsi } },
118098 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateitf" } } },117929 .{ .type = .usize, .kind = .{ .extern_func = "__floateitf" } },
118099 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117930 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
118100 .unused,117931 .unused,
118101 .unused,117932 .unused,
...@@ -118129,7 +117960,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -118129,7 +117960,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
118129 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117960 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
118130 .{ .type = .usize, .kind = .{ .reg = .rdi } },117961 .{ .type = .usize, .kind = .{ .reg = .rdi } },
118131 .{ .type = .usize, .kind = .{ .reg = .rsi } },117962 .{ .type = .usize, .kind = .{ .reg = .rsi } },
118132 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateitf" } } },117963 .{ .type = .usize, .kind = .{ .extern_func = "__floateitf" } },
118133 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117964 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
118134 .unused,117965 .unused,
118135 .unused,117966 .unused,
...@@ -118163,7 +117994,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -118163,7 +117994,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
118163 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },117994 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
118164 .{ .type = .usize, .kind = .{ .reg = .rdi } },117995 .{ .type = .usize, .kind = .{ .reg = .rdi } },
118165 .{ .type = .usize, .kind = .{ .reg = .rsi } },117996 .{ .type = .usize, .kind = .{ .reg = .rsi } },
118166 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floateitf" } } },117997 .{ .type = .usize, .kind = .{ .extern_func = "__floateitf" } },
118167 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },117998 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
118168 .unused,117999 .unused,
118169 .unused,118000 .unused,
...@@ -118197,7 +118028,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -118197,7 +118028,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
118197 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },118028 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
118198 .{ .type = .usize, .kind = .{ .reg = .rdi } },118029 .{ .type = .usize, .kind = .{ .reg = .rdi } },
118199 .{ .type = .usize, .kind = .{ .reg = .rsi } },118030 .{ .type = .usize, .kind = .{ .reg = .rsi } },
118200 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneitf" } } },118031 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneitf" } },
118201 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },118032 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
118202 .unused,118033 .unused,
118203 .unused,118034 .unused,
...@@ -118231,7 +118062,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -118231,7 +118062,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
118231 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },118062 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
118232 .{ .type = .usize, .kind = .{ .reg = .rdi } },118063 .{ .type = .usize, .kind = .{ .reg = .rdi } },
118233 .{ .type = .usize, .kind = .{ .reg = .rsi } },118064 .{ .type = .usize, .kind = .{ .reg = .rsi } },
118234 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneitf" } } },118065 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneitf" } },
118235 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },118066 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
118236 .unused,118067 .unused,
118237 .unused,118068 .unused,
...@@ -118265,7 +118096,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -118265,7 +118096,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
118265 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },118096 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
118266 .{ .type = .usize, .kind = .{ .reg = .rdi } },118097 .{ .type = .usize, .kind = .{ .reg = .rdi } },
118267 .{ .type = .usize, .kind = .{ .reg = .rsi } },118098 .{ .type = .usize, .kind = .{ .reg = .rsi } },
118268 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__floatuneitf" } } },118099 .{ .type = .usize, .kind = .{ .extern_func = "__floatuneitf" } },
118269 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },118100 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
118270 .unused,118101 .unused,
118271 .unused,118102 .unused,
...@@ -131980,7 +131811,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -131980,7 +131811,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
131980 .extra_temps = .{131811 .extra_temps = .{
131981 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },131812 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
131982 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },131813 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
131983 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fminh" } } },131814 .{ .type = .usize, .kind = .{ .extern_func = "__fminh" } },
131984 .unused,131815 .unused,
131985 .unused,131816 .unused,
131986 .unused,131817 .unused,
...@@ -132013,7 +131844,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -132013,7 +131844,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
132013 .extra_temps = .{131844 .extra_temps = .{
132014 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },131845 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
132015 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },131846 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
132016 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fminh" } } },131847 .{ .type = .usize, .kind = .{ .extern_func = "__fminh" } },
132017 .unused,131848 .unused,
132018 .unused,131849 .unused,
132019 .unused,131850 .unused,
...@@ -132048,7 +131879,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -132048,7 +131879,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
132048 .{ .type = .f16, .kind = .{ .reg = .ax } },131879 .{ .type = .f16, .kind = .{ .reg = .ax } },
132049 .{ .type = .f32, .kind = .mem },131880 .{ .type = .f32, .kind = .mem },
132050 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },131881 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
132051 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fminh" } } },131882 .{ .type = .usize, .kind = .{ .extern_func = "__fminh" } },
132052 .unused,131883 .unused,
132053 .unused,131884 .unused,
132054 .unused,131885 .unused,
...@@ -133648,7 +133479,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -133648,7 +133479,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
133648 .extra_temps = .{133479 .extra_temps = .{
133649 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },133480 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
133650 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },133481 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
133651 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fminq" } } },133482 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
133652 .unused,133483 .unused,
133653 .unused,133484 .unused,
133654 .unused,133485 .unused,
...@@ -133679,7 +133510,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -133679,7 +133510,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
133679 .extra_temps = .{133510 .extra_temps = .{
133680 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },133511 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
133681 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },133512 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
133682 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fminq" } } },133513 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
133683 .unused,133514 .unused,
133684 .unused,133515 .unused,
133685 .unused,133516 .unused,
...@@ -133710,7 +133541,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -133710,7 +133541,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
133710 .extra_temps = .{133541 .extra_temps = .{
133711 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },133542 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
133712 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },133543 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
133713 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fminq" } } },133544 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
133714 .unused,133545 .unused,
133715 .unused,133546 .unused,
133716 .unused,133547 .unused,
...@@ -142100,7 +141931,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -142100,7 +141931,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
142100 .extra_temps = .{141931 .extra_temps = .{
142101 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },141932 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
142102 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },141933 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
142103 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmaxh" } } },141934 .{ .type = .usize, .kind = .{ .extern_func = "__fmaxh" } },
142104 .unused,141935 .unused,
142105 .unused,141936 .unused,
142106 .unused,141937 .unused,
...@@ -142133,7 +141964,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -142133,7 +141964,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
142133 .extra_temps = .{141964 .extra_temps = .{
142134 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },141965 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
142135 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },141966 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
142136 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmaxh" } } },141967 .{ .type = .usize, .kind = .{ .extern_func = "__fmaxh" } },
142137 .unused,141968 .unused,
142138 .unused,141969 .unused,
142139 .unused,141970 .unused,
...@@ -142168,7 +141999,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -142168,7 +141999,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
142168 .{ .type = .f16, .kind = .{ .reg = .ax } },141999 .{ .type = .f16, .kind = .{ .reg = .ax } },
142169 .{ .type = .f32, .kind = .mem },142000 .{ .type = .f32, .kind = .mem },
142170 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },142001 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
142171 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmaxh" } } },142002 .{ .type = .usize, .kind = .{ .extern_func = "__fmaxh" } },
142172 .unused,142003 .unused,
142173 .unused,142004 .unused,
142174 .unused,142005 .unused,
...@@ -143776,7 +143607,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -143776,7 +143607,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
143776 .extra_temps = .{143607 .extra_temps = .{
143777 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },143608 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
143778 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },143609 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
143779 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaxq" } } },143610 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
143780 .unused,143611 .unused,
143781 .unused,143612 .unused,
143782 .unused,143613 .unused,
...@@ -143807,7 +143638,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -143807,7 +143638,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
143807 .extra_temps = .{143638 .extra_temps = .{
143808 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },143639 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
143809 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },143640 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
143810 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaxq" } } },143641 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
143811 .unused,143642 .unused,
143812 .unused,143643 .unused,
143813 .unused,143644 .unused,
...@@ -143838,7 +143669,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -143838,7 +143669,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
143838 .extra_temps = .{143669 .extra_temps = .{
143839 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },143670 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
143840 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },143671 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
143841 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaxq" } } },143672 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
143842 .unused,143673 .unused,
143843 .unused,143674 .unused,
143844 .unused,143675 .unused,
...@@ -147771,7 +147602,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -147771,7 +147602,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
147771 .extra_temps = .{147602 .extra_temps = .{
147772 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },147603 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
147773 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },147604 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
147774 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },147605 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
147775 .unused,147606 .unused,
147776 .unused,147607 .unused,
147777 .unused,147608 .unused,
...@@ -147804,7 +147635,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -147804,7 +147635,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
147804 .extra_temps = .{147635 .extra_temps = .{
147805 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },147636 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
147806 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },147637 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
147807 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },147638 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
147808 .unused,147639 .unused,
147809 .unused,147640 .unused,
147810 .unused,147641 .unused,
...@@ -147839,7 +147670,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -147839,7 +147670,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
147839 .{ .type = .f16, .kind = .{ .reg = .ax } },147670 .{ .type = .f16, .kind = .{ .reg = .ax } },
147840 .{ .type = .f32, .kind = .mem },147671 .{ .type = .f32, .kind = .mem },
147841 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },147672 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
147842 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },147673 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
147843 .unused,147674 .unused,
147844 .unused,147675 .unused,
147845 .unused,147676 .unused,
...@@ -148356,7 +148187,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -148356,7 +148187,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
148356 .extra_temps = .{148187 .extra_temps = .{
148357 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },148188 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
148358 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },148189 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
148359 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },148190 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
148360 .unused,148191 .unused,
148361 .unused,148192 .unused,
148362 .unused,148193 .unused,
...@@ -148387,7 +148218,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -148387,7 +148218,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
148387 .extra_temps = .{148218 .extra_temps = .{
148388 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },148219 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
148389 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },148220 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
148390 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },148221 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
148391 .unused,148222 .unused,
148392 .unused,148223 .unused,
148393 .unused,148224 .unused,
...@@ -148418,7 +148249,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -148418,7 +148249,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
148418 .extra_temps = .{148249 .extra_temps = .{
148419 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },148250 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
148420 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },148251 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
148421 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },148252 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
148422 .unused,148253 .unused,
148423 .unused,148254 .unused,
148424 .unused,148255 .unused,
...@@ -151430,7 +151261,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -151430,7 +151261,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
151430 .extra_temps = .{151261 .extra_temps = .{
151431 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },151262 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
151432 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },151263 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
151433 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },151264 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
151434 .unused,151265 .unused,
151435 .unused,151266 .unused,
151436 .unused,151267 .unused,
...@@ -151463,7 +151294,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -151463,7 +151294,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
151463 .extra_temps = .{151294 .extra_temps = .{
151464 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },151295 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
151465 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },151296 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
151466 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },151297 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
151467 .unused,151298 .unused,
151468 .unused,151299 .unused,
151469 .unused,151300 .unused,
...@@ -151498,7 +151329,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -151498,7 +151329,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
151498 .{ .type = .f16, .kind = .{ .reg = .ax } },151329 .{ .type = .f16, .kind = .{ .reg = .ax } },
151499 .{ .type = .f32, .kind = .mem },151330 .{ .type = .f32, .kind = .mem },
151500 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },151331 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
151501 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },151332 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
151502 .unused,151333 .unused,
151503 .unused,151334 .unused,
151504 .unused,151335 .unused,
...@@ -151895,7 +151726,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -151895,7 +151726,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
151895 .extra_temps = .{151726 .extra_temps = .{
151896 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },151727 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
151897 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },151728 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
151898 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },151729 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
151899 .unused,151730 .unused,
151900 .unused,151731 .unused,
151901 .unused,151732 .unused,
...@@ -151926,7 +151757,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -151926,7 +151757,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
151926 .extra_temps = .{151757 .extra_temps = .{
151927 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },151758 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
151928 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },151759 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
151929 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },151760 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
151930 .unused,151761 .unused,
151931 .unused,151762 .unused,
151932 .unused,151763 .unused,
...@@ -151957,7 +151788,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -151957,7 +151788,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
151957 .extra_temps = .{151788 .extra_temps = .{
151958 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },151789 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
151959 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },151790 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
151960 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },151791 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
151961 .unused,151792 .unused,
151962 .unused,151793 .unused,
151963 .unused,151794 .unused,
...@@ -152469,7 +152300,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -152469,7 +152300,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
152469 .extra_temps = .{152300 .extra_temps = .{
152470 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },152301 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
152471 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },152302 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
152472 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fminh" } } },152303 .{ .type = .usize, .kind = .{ .extern_func = "__fminh" } },
152473 .unused,152304 .unused,
152474 .unused,152305 .unused,
152475 .unused,152306 .unused,
...@@ -152502,7 +152333,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -152502,7 +152333,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
152502 .extra_temps = .{152333 .extra_temps = .{
152503 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },152334 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
152504 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },152335 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
152505 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fminh" } } },152336 .{ .type = .usize, .kind = .{ .extern_func = "__fminh" } },
152506 .unused,152337 .unused,
152507 .unused,152338 .unused,
152508 .unused,152339 .unused,
...@@ -152537,7 +152368,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -152537,7 +152368,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
152537 .{ .type = .f16, .kind = .{ .reg = .ax } },152368 .{ .type = .f16, .kind = .{ .reg = .ax } },
152538 .{ .type = .f32, .kind = .mem },152369 .{ .type = .f32, .kind = .mem },
152539 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },152370 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
152540 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fminh" } } },152371 .{ .type = .usize, .kind = .{ .extern_func = "__fminh" } },
152541 .unused,152372 .unused,
152542 .unused,152373 .unused,
152543 .unused,152374 .unused,
...@@ -153617,7 +153448,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -153617,7 +153448,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
153617 .extra_temps = .{153448 .extra_temps = .{
153618 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },153449 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
153619 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },153450 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
153620 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fminq" } } },153451 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
153621 .unused,153452 .unused,
153622 .unused,153453 .unused,
153623 .unused,153454 .unused,
...@@ -153648,7 +153479,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -153648,7 +153479,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
153648 .extra_temps = .{153479 .extra_temps = .{
153649 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },153480 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
153650 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },153481 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
153651 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fminq" } } },153482 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
153652 .unused,153483 .unused,
153653 .unused,153484 .unused,
153654 .unused,153485 .unused,
...@@ -153679,7 +153510,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -153679,7 +153510,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
153679 .extra_temps = .{153510 .extra_temps = .{
153680 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },153511 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
153681 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },153512 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
153682 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fminq" } } },153513 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
153683 .unused,153514 .unused,
153684 .unused,153515 .unused,
153685 .unused,153516 .unused,
...@@ -154161,7 +153992,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -154161,7 +153992,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
154161 .extra_temps = .{153992 .extra_temps = .{
154162 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },153993 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
154163 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },153994 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
154164 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmaxh" } } },153995 .{ .type = .usize, .kind = .{ .extern_func = "__fmaxh" } },
154165 .unused,153996 .unused,
154166 .unused,153997 .unused,
154167 .unused,153998 .unused,
...@@ -154194,7 +154025,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -154194,7 +154025,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
154194 .extra_temps = .{154025 .extra_temps = .{
154195 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },154026 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
154196 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },154027 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
154197 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmaxh" } } },154028 .{ .type = .usize, .kind = .{ .extern_func = "__fmaxh" } },
154198 .unused,154029 .unused,
154199 .unused,154030 .unused,
154200 .unused,154031 .unused,
...@@ -154229,7 +154060,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -154229,7 +154060,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
154229 .{ .type = .f16, .kind = .{ .reg = .ax } },154060 .{ .type = .f16, .kind = .{ .reg = .ax } },
154230 .{ .type = .f32, .kind = .mem },154061 .{ .type = .f32, .kind = .mem },
154231 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },154062 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
154232 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmaxh" } } },154063 .{ .type = .usize, .kind = .{ .extern_func = "__fmaxh" } },
154233 .unused,154064 .unused,
154234 .unused,154065 .unused,
154235 .unused,154066 .unused,
...@@ -155309,7 +155140,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -155309,7 +155140,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
155309 .extra_temps = .{155140 .extra_temps = .{
155310 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },155141 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
155311 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },155142 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
155312 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaxq" } } },155143 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
155313 .unused,155144 .unused,
155314 .unused,155145 .unused,
155315 .unused,155146 .unused,
...@@ -155340,7 +155171,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -155340,7 +155171,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
155340 .extra_temps = .{155171 .extra_temps = .{
155341 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },155172 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
155342 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },155173 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
155343 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaxq" } } },155174 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
155344 .unused,155175 .unused,
155345 .unused,155176 .unused,
155346 .unused,155177 .unused,
...@@ -155371,7 +155202,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -155371,7 +155202,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
155371 .extra_temps = .{155202 .extra_temps = .{
155372 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },155203 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
155373 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },155204 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
155374 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaxq" } } },155205 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
155375 .unused,155206 .unused,
155376 .unused,155207 .unused,
155377 .unused,155208 .unused,
...@@ -156102,7 +155933,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -156102,7 +155933,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
156102 .extra_temps = .{155933 .extra_temps = .{
156103 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },155934 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
156104 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },155935 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
156105 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },155936 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
156106 .unused,155937 .unused,
156107 .unused,155938 .unused,
156108 .unused,155939 .unused,
...@@ -156135,7 +155966,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -156135,7 +155966,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
156135 .extra_temps = .{155966 .extra_temps = .{
156136 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },155967 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
156137 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },155968 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
156138 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },155969 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
156139 .unused,155970 .unused,
156140 .unused,155971 .unused,
156141 .unused,155972 .unused,
...@@ -156170,7 +156001,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -156170,7 +156001,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
156170 .{ .type = .f16, .kind = .{ .reg = .ax } },156001 .{ .type = .f16, .kind = .{ .reg = .ax } },
156171 .{ .type = .f32, .kind = .mem },156002 .{ .type = .f32, .kind = .mem },
156172 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },156003 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
156173 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addhf3" } } },156004 .{ .type = .usize, .kind = .{ .extern_func = "__addhf3" } },
156174 .unused,156005 .unused,
156175 .unused,156006 .unused,
156176 .unused,156007 .unused,
...@@ -157568,7 +157399,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -157568,7 +157399,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
157568 .extra_temps = .{157399 .extra_temps = .{
157569 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },157400 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
157570 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },157401 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
157571 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },157402 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
157572 .unused,157403 .unused,
157573 .unused,157404 .unused,
157574 .unused,157405 .unused,
...@@ -157599,7 +157430,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -157599,7 +157430,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
157599 .extra_temps = .{157430 .extra_temps = .{
157600 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },157431 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
157601 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },157432 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
157602 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },157433 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
157603 .unused,157434 .unused,
157604 .unused,157435 .unused,
157605 .unused,157436 .unused,
...@@ -157630,7 +157461,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -157630,7 +157461,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
157630 .extra_temps = .{157461 .extra_temps = .{
157631 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },157462 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
157632 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },157463 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
157633 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__addtf3" } } },157464 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
157634 .unused,157465 .unused,
157635 .unused,157466 .unused,
157636 .unused,157467 .unused,
...@@ -158112,7 +157943,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -158112,7 +157943,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
158112 .extra_temps = .{157943 .extra_temps = .{
158113 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },157944 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
158114 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },157945 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
158115 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },157946 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
158116 .unused,157947 .unused,
158117 .unused,157948 .unused,
158118 .unused,157949 .unused,
...@@ -158145,7 +157976,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -158145,7 +157976,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
158145 .extra_temps = .{157976 .extra_temps = .{
158146 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },157977 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
158147 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },157978 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
158148 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },157979 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
158149 .unused,157980 .unused,
158150 .unused,157981 .unused,
158151 .unused,157982 .unused,
...@@ -158180,7 +158011,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -158180,7 +158011,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
158180 .{ .type = .f16, .kind = .{ .reg = .ax } },158011 .{ .type = .f16, .kind = .{ .reg = .ax } },
158181 .{ .type = .f32, .kind = .mem },158012 .{ .type = .f32, .kind = .mem },
158182 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },158013 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
158183 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__mulhf3" } } },158014 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
158184 .unused,158015 .unused,
158185 .unused,158016 .unused,
158186 .unused,158017 .unused,
...@@ -159111,7 +158942,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -159111,7 +158942,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
159111 .extra_temps = .{158942 .extra_temps = .{
159112 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },158943 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
159113 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },158944 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
159114 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },158945 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
159115 .unused,158946 .unused,
159116 .unused,158947 .unused,
159117 .unused,158948 .unused,
...@@ -159142,7 +158973,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -159142,7 +158973,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
159142 .extra_temps = .{158973 .extra_temps = .{
159143 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },158974 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
159144 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },158975 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
159145 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },158976 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
159146 .unused,158977 .unused,
159147 .unused,158978 .unused,
159148 .unused,158979 .unused,
...@@ -159173,7 +159004,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -159173,7 +159004,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
159173 .extra_temps = .{159004 .extra_temps = .{
159174 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },159005 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
159175 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },159006 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
159176 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__multf3" } } },159007 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
159177 .unused,159008 .unused,
159178 .unused,159009 .unused,
159179 .unused,159010 .unused,
...@@ -161054,7 +160885,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161054,7 +160885,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161054 },160885 },
161055 .call_frame = .{ .alignment = .@"16" },160886 .call_frame = .{ .alignment = .@"16" },
161056 .extra_temps = .{160887 .extra_temps = .{
161057 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = @tagName(symbol) } } },160888 .{ .type = .usize, .kind = .{ .extern_func = @tagName(symbol) } },
161058 .unused,160889 .unused,
161059 .unused,160890 .unused,
161060 .unused,160891 .unused,
...@@ -161103,7 +160934,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161103,7 +160934,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161103 },160934 },
161104 .call_frame = .{ .alignment = .@"32" },160935 .call_frame = .{ .alignment = .@"32" },
161105 .extra_temps = .{160936 .extra_temps = .{
161106 .{ .type = .usize, .kind = .{ .lazy_symbol = .{ .kind = .code, .ref = .src0 } } },160937 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .code, .ref = .src0 } } },
161107 .unused,160938 .unused,
161108 .unused,160939 .unused,
161109 .unused,160940 .unused,
...@@ -161129,7 +160960,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161129,7 +160960,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161129 },160960 },
161130 .call_frame = .{ .alignment = .@"16" },160961 .call_frame = .{ .alignment = .@"16" },
161131 .extra_temps = .{160962 .extra_temps = .{
161132 .{ .type = .usize, .kind = .{ .lazy_symbol = .{ .kind = .code, .ref = .src0 } } },160963 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .code, .ref = .src0 } } },
161133 .unused,160964 .unused,
161134 .unused,160965 .unused,
161135 .unused,160966 .unused,
...@@ -161154,7 +160985,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161154,7 +160985,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161154 },160985 },
161155 .call_frame = .{ .alignment = .@"8" },160986 .call_frame = .{ .alignment = .@"8" },
161156 .extra_temps = .{160987 .extra_temps = .{
161157 .{ .type = .usize, .kind = .{ .lazy_symbol = .{ .kind = .code, .ref = .src0 } } },160988 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .code, .ref = .src0 } } },
161158 .unused,160989 .unused,
161159 .unused,160990 .unused,
161160 .unused,160991 .unused,
...@@ -161194,7 +161025,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161194,7 +161025,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161194 },161025 },
161195 .call_frame = .{ .alignment = .@"32" },161026 .call_frame = .{ .alignment = .@"32" },
161196 .extra_temps = .{161027 .extra_temps = .{
161197 .{ .type = .usize, .kind = .{ .lazy_symbol = .{ .kind = .code, .ref = .src0 } } },161028 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .code, .ref = .src0 } } },
161198 .unused,161029 .unused,
161199 .unused,161030 .unused,
161200 .unused,161031 .unused,
...@@ -161219,7 +161050,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161219,7 +161050,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161219 },161050 },
161220 .call_frame = .{ .alignment = .@"16" },161051 .call_frame = .{ .alignment = .@"16" },
161221 .extra_temps = .{161052 .extra_temps = .{
161222 .{ .type = .usize, .kind = .{ .lazy_symbol = .{ .kind = .code, .ref = .src0 } } },161053 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .code, .ref = .src0 } } },
161223 .unused,161054 .unused,
161224 .unused,161055 .unused,
161225 .unused,161056 .unused,
...@@ -161243,7 +161074,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161243,7 +161074,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161243 },161074 },
161244 .call_frame = .{ .alignment = .@"8" },161075 .call_frame = .{ .alignment = .@"8" },
161245 .extra_temps = .{161076 .extra_temps = .{
161246 .{ .type = .usize, .kind = .{ .lazy_symbol = .{ .kind = .code, .ref = .src0 } } },161077 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .code, .ref = .src0 } } },
161247 .unused,161078 .unused,
161248 .unused,161079 .unused,
161249 .unused,161080 .unused,
...@@ -161282,7 +161113,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161282,7 +161113,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161282 .{ .src = .{ .to_gpr, .none, .none } },161113 .{ .src = .{ .to_gpr, .none, .none } },
161283 },161114 },
161284 .extra_temps = .{161115 .extra_temps = .{
161285 .{ .type = .anyerror, .kind = .{ .lazy_symbol = .{ .kind = .const_data } } },161116 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },
161286 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },161117 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },
161287 .unused,161118 .unused,
161288 .unused,161119 .unused,
...@@ -161311,7 +161142,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161311,7 +161142,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161311 .{ .src = .{ .to_gpr, .none, .none } },161142 .{ .src = .{ .to_gpr, .none, .none } },
161312 },161143 },
161313 .extra_temps = .{161144 .extra_temps = .{
161314 .{ .type = .anyerror, .kind = .{ .lazy_symbol = .{ .kind = .const_data } } },161145 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },
161315 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },161146 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },
161316 .unused,161147 .unused,
161317 .unused,161148 .unused,
...@@ -161340,7 +161171,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161340,7 +161171,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161340 .{ .src = .{ .to_gpr, .none, .none } },161171 .{ .src = .{ .to_gpr, .none, .none } },
161341 },161172 },
161342 .extra_temps = .{161173 .extra_temps = .{
161343 .{ .type = .anyerror, .kind = .{ .lazy_symbol = .{ .kind = .const_data } } },161174 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },
161344 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },161175 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },
161345 .unused,161176 .unused,
161346 .unused,161177 .unused,
...@@ -161391,7 +161222,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161391,7 +161222,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161391 },161222 },
161392 .call_frame = .{ .alignment = .@"32" },161223 .call_frame = .{ .alignment = .@"32" },
161393 .extra_temps = .{161224 .extra_temps = .{
161394 .{ .type = .usize, .kind = .{ .lazy_symbol = .{ .kind = .code, .ref = .src1 } } },161225 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .code, .ref = .src1 } } },
161395 .unused,161226 .unused,
161396 .unused,161227 .unused,
161397 .unused,161228 .unused,
...@@ -161417,7 +161248,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161417,7 +161248,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161417 },161248 },
161418 .call_frame = .{ .alignment = .@"16" },161249 .call_frame = .{ .alignment = .@"16" },
161419 .extra_temps = .{161250 .extra_temps = .{
161420 .{ .type = .usize, .kind = .{ .lazy_symbol = .{ .kind = .code, .ref = .src1 } } },161251 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .code, .ref = .src1 } } },
161421 .unused,161252 .unused,
161422 .unused,161253 .unused,
161423 .unused,161254 .unused,
...@@ -161442,7 +161273,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161442,7 +161273,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161442 },161273 },
161443 .call_frame = .{ .alignment = .@"8" },161274 .call_frame = .{ .alignment = .@"8" },
161444 .extra_temps = .{161275 .extra_temps = .{
161445 .{ .type = .usize, .kind = .{ .lazy_symbol = .{ .kind = .code, .ref = .src1 } } },161276 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .code, .ref = .src1 } } },
161446 .unused,161277 .unused,
161447 .unused,161278 .unused,
161448 .unused,161279 .unused,
...@@ -161638,7 +161469,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161638,7 +161469,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161638 },161469 },
161639 .call_frame = .{ .alignment = .@"16" },161470 .call_frame = .{ .alignment = .@"16" },
161640 .extra_temps = .{161471 .extra_temps = .{
161641 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmah" } } },161472 .{ .type = .usize, .kind = .{ .extern_func = "__fmah" } },
161642 .unused,161473 .unused,
161643 .unused,161474 .unused,
161644 .unused,161475 .unused,
...@@ -161781,7 +161612,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161781,7 +161612,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161781 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },161612 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
161782 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },161613 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
161783 .{ .type = .f16, .kind = .{ .reg = .xmm2 } },161614 .{ .type = .f16, .kind = .{ .reg = .xmm2 } },
161784 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmah" } } },161615 .{ .type = .usize, .kind = .{ .extern_func = "__fmah" } },
161785 .unused,161616 .unused,
161786 .unused,161617 .unused,
161787 .unused,161618 .unused,
...@@ -161818,7 +161649,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161818,7 +161649,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161818 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },161649 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
161819 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },161650 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
161820 .{ .type = .f16, .kind = .{ .reg = .xmm2 } },161651 .{ .type = .f16, .kind = .{ .reg = .xmm2 } },
161821 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmah" } } },161652 .{ .type = .usize, .kind = .{ .extern_func = "__fmah" } },
161822 .unused,161653 .unused,
161823 .unused,161654 .unused,
161824 .unused,161655 .unused,
...@@ -161857,7 +161688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161857,7 +161688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161857 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },161688 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
161858 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },161689 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
161859 .{ .type = .f16, .kind = .{ .reg = .xmm2 } },161690 .{ .type = .f16, .kind = .{ .reg = .xmm2 } },
161860 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmah" } } },161691 .{ .type = .usize, .kind = .{ .extern_func = "__fmah" } },
161861 .{ .type = .f16, .kind = .{ .reg = .ax } },161692 .{ .type = .f16, .kind = .{ .reg = .ax } },
161862 .unused,161693 .unused,
161863 .unused,161694 .unused,
...@@ -161899,7 +161730,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161899,7 +161730,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161899 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },161730 .{ .type = .f16, .kind = .{ .reg = .xmm0 } },
161900 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },161731 .{ .type = .f16, .kind = .{ .reg = .xmm1 } },
161901 .{ .type = .f16, .kind = .{ .reg = .xmm2 } },161732 .{ .type = .f16, .kind = .{ .reg = .xmm2 } },
161902 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmah" } } },161733 .{ .type = .usize, .kind = .{ .extern_func = "__fmah" } },
161903 .unused,161734 .unused,
161904 .unused,161735 .unused,
161905 .unused,161736 .unused,
...@@ -161987,7 +161818,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161987,7 +161818,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161987 },161818 },
161988 .call_frame = .{ .alignment = .@"16" },161819 .call_frame = .{ .alignment = .@"16" },
161989 .extra_temps = .{161820 .extra_temps = .{
161990 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaf" } } },161821 .{ .type = .usize, .kind = .{ .extern_func = "fmaf" } },
161991 .unused,161822 .unused,
161992 .unused,161823 .unused,
161993 .unused,161824 .unused,
...@@ -162153,7 +161984,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162153,7 +161984,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162153 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },161984 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
162154 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },161985 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },
162155 .{ .type = .f32, .kind = .{ .reg = .xmm2 } },161986 .{ .type = .f32, .kind = .{ .reg = .xmm2 } },
162156 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaf" } } },161987 .{ .type = .usize, .kind = .{ .extern_func = "fmaf" } },
162157 .unused,161988 .unused,
162158 .unused,161989 .unused,
162159 .unused,161990 .unused,
...@@ -162189,7 +162020,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162189,7 +162020,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162189 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },162020 .{ .type = .f32, .kind = .{ .reg = .xmm0 } },
162190 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },162021 .{ .type = .f32, .kind = .{ .reg = .xmm1 } },
162191 .{ .type = .f32, .kind = .{ .reg = .xmm2 } },162022 .{ .type = .f32, .kind = .{ .reg = .xmm2 } },
162192 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaf" } } },162023 .{ .type = .usize, .kind = .{ .extern_func = "fmaf" } },
162193 .unused,162024 .unused,
162194 .unused,162025 .unused,
162195 .unused,162026 .unused,
...@@ -162271,7 +162102,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162271,7 +162102,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162271 },162102 },
162272 .call_frame = .{ .alignment = .@"16" },162103 .call_frame = .{ .alignment = .@"16" },
162273 .extra_temps = .{162104 .extra_temps = .{
162274 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fma" } } },162105 .{ .type = .usize, .kind = .{ .extern_func = "fma" } },
162275 .unused,162106 .unused,
162276 .unused,162107 .unused,
162277 .unused,162108 .unused,
...@@ -162437,7 +162268,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162437,7 +162268,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162437 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },162268 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
162438 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },162269 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
162439 .{ .type = .f64, .kind = .{ .reg = .xmm2 } },162270 .{ .type = .f64, .kind = .{ .reg = .xmm2 } },
162440 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fma" } } },162271 .{ .type = .usize, .kind = .{ .extern_func = "fma" } },
162441 .unused,162272 .unused,
162442 .unused,162273 .unused,
162443 .unused,162274 .unused,
...@@ -162473,7 +162304,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162473,7 +162304,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162473 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },162304 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
162474 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },162305 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
162475 .{ .type = .f64, .kind = .{ .reg = .xmm2 } },162306 .{ .type = .f64, .kind = .{ .reg = .xmm2 } },
162476 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fma" } } },162307 .{ .type = .usize, .kind = .{ .extern_func = "fma" } },
162477 .unused,162308 .unused,
162478 .unused,162309 .unused,
162479 .unused,162310 .unused,
...@@ -162509,7 +162340,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162509,7 +162340,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162509 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },162340 .{ .type = .f64, .kind = .{ .reg = .xmm0 } },
162510 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },162341 .{ .type = .f64, .kind = .{ .reg = .xmm1 } },
162511 .{ .type = .f64, .kind = .{ .reg = .xmm2 } },162342 .{ .type = .f64, .kind = .{ .reg = .xmm2 } },
162512 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fma" } } },162343 .{ .type = .usize, .kind = .{ .extern_func = "fma" } },
162513 .unused,162344 .unused,
162514 .unused,162345 .unused,
162515 .unused,162346 .unused,
...@@ -162546,7 +162377,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162546,7 +162377,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162546 .extra_temps = .{162377 .extra_temps = .{
162547 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },162378 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
162548 .{ .type = .f80, .kind = .{ .frame = .call_frame } },162379 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
162549 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmax" } } },162380 .{ .type = .usize, .kind = .{ .extern_func = "__fmax" } },
162550 .unused,162381 .unused,
162551 .unused,162382 .unused,
162552 .unused,162383 .unused,
...@@ -162582,7 +162413,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162582,7 +162413,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162582 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },162413 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
162583 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },162414 .{ .type = .f80, .kind = .{ .reg = .xmm0 } },
162584 .{ .type = .f80, .kind = .{ .frame = .call_frame } },162415 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
162585 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__fmax" } } },162416 .{ .type = .usize, .kind = .{ .extern_func = "__fmax" } },
162586 .unused,162417 .unused,
162587 .unused,162418 .unused,
162588 .unused,162419 .unused,
...@@ -162619,7 +162450,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162619,7 +162450,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162619 },162450 },
162620 .call_frame = .{ .alignment = .@"16" },162451 .call_frame = .{ .alignment = .@"16" },
162621 .extra_temps = .{162452 .extra_temps = .{
162622 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaq" } } },162453 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },
162623 .unused,162454 .unused,
162624 .unused,162455 .unused,
162625 .unused,162456 .unused,
...@@ -162652,7 +162483,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162652,7 +162483,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162652 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },162483 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
162653 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },162484 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
162654 .{ .type = .f128, .kind = .{ .reg = .xmm2 } },162485 .{ .type = .f128, .kind = .{ .reg = .xmm2 } },
162655 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaq" } } },162486 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },
162656 .unused,162487 .unused,
162657 .unused,162488 .unused,
162658 .unused,162489 .unused,
...@@ -162688,7 +162519,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162688,7 +162519,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162688 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },162519 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
162689 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },162520 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
162690 .{ .type = .f128, .kind = .{ .reg = .xmm2 } },162521 .{ .type = .f128, .kind = .{ .reg = .xmm2 } },
162691 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaq" } } },162522 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },
162692 .unused,162523 .unused,
162693 .unused,162524 .unused,
162694 .unused,162525 .unused,
...@@ -162724,7 +162555,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162724,7 +162555,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162724 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },162555 .{ .type = .f128, .kind = .{ .reg = .xmm0 } },
162725 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },162556 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
162726 .{ .type = .f128, .kind = .{ .reg = .xmm2 } },162557 .{ .type = .f128, .kind = .{ .reg = .xmm2 } },
162727 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "fmaq" } } },162558 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },
162728 .unused,162559 .unused,
162729 .unused,162560 .unused,
162730 .unused,162561 .unused,
...@@ -162778,7 +162609,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162778,7 +162609,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162778 .{ .src = .{ .to_gpr, .none, .none } },162609 .{ .src = .{ .to_gpr, .none, .none } },
162779 },162610 },
162780 .extra_temps = .{162611 .extra_temps = .{
162781 .{ .type = .anyerror, .kind = .{ .lazy_symbol = .{ .kind = .const_data } } },162612 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },
162782 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },162613 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
162783 .unused,162614 .unused,
162784 .unused,162615 .unused,
...@@ -162802,7 +162633,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162802,7 +162633,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162802 .{ .src = .{ .to_gpr, .none, .none } },162633 .{ .src = .{ .to_gpr, .none, .none } },
162803 },162634 },
162804 .extra_temps = .{162635 .extra_temps = .{
162805 .{ .type = .anyerror, .kind = .{ .lazy_symbol = .{ .kind = .const_data } } },162636 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },
162806 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },162637 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
162807 .unused,162638 .unused,
162808 .unused,162639 .unused,
...@@ -162826,7 +162657,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -162826,7 +162657,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162826 .{ .src = .{ .to_gpr, .none, .none } },162657 .{ .src = .{ .to_gpr, .none, .none } },
162827 },162658 },
162828 .extra_temps = .{162659 .extra_temps = .{
162829 .{ .type = .anyerror, .kind = .{ .lazy_symbol = .{ .kind = .const_data } } },162660 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },
162830 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },162661 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
162831 .unused,162662 .unused,
162832 .unused,162663 .unused,
...@@ -163517,65 +163348,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -163517,65 +163348,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
163517 };163348 };
163518 for (ops) |op| try op.die(cg);163349 for (ops) |op| try op.die(cg);
163519 },163350 },
163520 .runtime_nav_ptr => switch (cg.bin_file.tag) {163351 .runtime_nav_ptr => {
163521 .elf, .macho => {163352 const ty_nav = air_datas[@intFromEnum(inst)].ty_nav;
163522 const ty_nav = air_datas[@intFromEnum(inst)].ty_nav;163353 const nav = ip.getNav(ty_nav.nav);
163523163354 const is_threadlocal = zcu.comp.config.any_non_single_threaded and nav.isThreadlocal(ip);
163524 const nav = ip.getNav(ty_nav.nav);163355 if (is_threadlocal) if (cg.mod.pic) {
163525 const sym_index, const relocation = sym: {163356 try cg.spillRegisters(&.{ .rdi, .rax });
163526 if (cg.bin_file.cast(.elf)) |elf_file| {163357 } else {
163527 const zo = elf_file.zigObjectPtr().?;163358 try cg.spillRegisters(&.{.rax});
163528 if (nav.getExtern(ip)) |e| {163359 };
163529 const sym = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), e.lib_name.toSlice(ip));163360 var res = try cg.tempInit(.fromInterned(ty_nav.ty), .{ .lea_nav = ty_nav.nav });
163530 linkage: switch (e.linkage) {163361 if (is_threadlocal) while (try res.toRegClass(true, .general_purpose, cg)) {};
163531 .internal => {},163362 try res.finish(inst, &.{}, &.{}, cg);
163532 .strong => switch (e.visibility) {
163533 .default => zo.symbol(sym).flags.is_extern_ptr = true,
163534 .hidden, .protected => {},
163535 },
163536 .weak => {
163537 zo.symbol(sym).flags.weak = true;
163538 continue :linkage .strong;
163539 },
163540 .link_once => unreachable,
163541 }
163542 break :sym .{ sym, e.relocation };
163543 } else break :sym .{ try zo.getOrCreateMetadataForNav(zcu, ty_nav.nav), .any };
163544 } else if (cg.bin_file.cast(.macho)) |macho_file| {
163545 const zo = macho_file.getZigObject().?;
163546 if (nav.getExtern(ip)) |e| {
163547 const sym = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), e.lib_name.toSlice(ip));
163548 linkage: switch (e.linkage) {
163549 .internal => {},
163550 .strong => switch (e.visibility) {
163551 .default => zo.symbols.items[sym].flags.is_extern_ptr = true,
163552 .hidden, .protected => {},
163553 },
163554 .weak => {
163555 zo.symbols.items[sym].flags.weak = true;
163556 continue :linkage .strong;
163557 },
163558 .link_once => unreachable,
163559 }
163560 break :sym .{ sym, e.relocation };
163561 } else break :sym .{ try zo.getOrCreateMetadataForNav(macho_file, ty_nav.nav), .any };
163562 } else unreachable;
163563 };
163564
163565 if (cg.mod.pic) {
163566 try cg.spillRegisters(&.{ .rdi, .rax });
163567 } else {
163568 try cg.spillRegisters(&.{.rax});
163569 }
163570
163571 var slot = try cg.tempInit(.usize, switch (relocation) {
163572 .any => .{ .lea_symbol = .{ .sym_index = sym_index } },
163573 .pcrel => .{ .lea_pcrel = .{ .sym_index = sym_index } },
163574 });
163575 while (try slot.toRegClass(true, .general_purpose, cg)) {}
163576 try slot.finish(inst, &.{}, &.{}, cg);
163577 },
163578 else => return cg.fail("TODO implement runtime_nav_ptr on {}", .{cg.bin_file.tag}),
163579 },163363 },
163580 .c_va_arg => try cg.airVaArg(inst),163364 .c_va_arg => try cg.airVaArg(inst),
163581 .c_va_copy => try cg.airVaCopy(inst),163365 .c_va_copy => try cg.airVaCopy(inst),
...@@ -164231,11 +164015,11 @@ fn airFptrunc(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -164231,11 +164015,11 @@ fn airFptrunc(self: *CodeGen, inst: Air.Inst.Index) !void {
164231 },164015 },
164232 else => unreachable,164016 else => unreachable,
164233 }) {164017 }) {
164234 var callee_buf: ["__trunc?f?f2".len]u8 = undefined;164018 var sym_buf: ["__trunc?f?f2".len]u8 = undefined;
164235 break :result try self.genCall(.{ .lib = .{164019 break :result try self.genCall(.{ .extern_func = .{
164236 .return_type = self.floatCompilerRtAbiType(dst_ty, src_ty).toIntern(),164020 .return_type = self.floatCompilerRtAbiType(dst_ty, src_ty).toIntern(),
164237 .param_types = &.{self.floatCompilerRtAbiType(src_ty, dst_ty).toIntern()},164021 .param_types = &.{self.floatCompilerRtAbiType(src_ty, dst_ty).toIntern()},
164238 .callee = std.fmt.bufPrint(&callee_buf, "__trunc{c}f{c}f2", .{164022 .sym = std.fmt.bufPrint(&sym_buf, "__trunc{c}f{c}f2", .{
164239 floatCompilerRtAbiName(src_bits),164023 floatCompilerRtAbiName(src_bits),
164240 floatCompilerRtAbiName(dst_bits),164024 floatCompilerRtAbiName(dst_bits),
164241 }) catch unreachable,164025 }) catch unreachable,
...@@ -164335,11 +164119,11 @@ fn airFpext(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -164335,11 +164119,11 @@ fn airFpext(self: *CodeGen, inst: Air.Inst.Index) !void {
164335 else => unreachable,164119 else => unreachable,
164336 }) {164120 }) {
164337 if (dst_ty.isVector(zcu)) break :result null;164121 if (dst_ty.isVector(zcu)) break :result null;
164338 var callee_buf: ["__extend?f?f2".len]u8 = undefined;164122 var sym_buf: ["__extend?f?f2".len]u8 = undefined;
164339 break :result try self.genCall(.{ .lib = .{164123 break :result try self.genCall(.{ .extern_func = .{
164340 .return_type = self.floatCompilerRtAbiType(dst_scalar_ty, src_scalar_ty).toIntern(),164124 .return_type = self.floatCompilerRtAbiType(dst_scalar_ty, src_scalar_ty).toIntern(),
164341 .param_types = &.{self.floatCompilerRtAbiType(src_scalar_ty, dst_scalar_ty).toIntern()},164125 .param_types = &.{self.floatCompilerRtAbiType(src_scalar_ty, dst_scalar_ty).toIntern()},
164342 .callee = std.fmt.bufPrint(&callee_buf, "__extend{c}f{c}f2", .{164126 .sym = std.fmt.bufPrint(&sym_buf, "__extend{c}f{c}f2", .{
164343 floatCompilerRtAbiName(src_bits),164127 floatCompilerRtAbiName(src_bits),
164344 floatCompilerRtAbiName(dst_bits),164128 floatCompilerRtAbiName(dst_bits),
164345 }) catch unreachable,164129 }) catch unreachable,
...@@ -164776,7 +164560,7 @@ fn airTrunc(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -164776,7 +164560,7 @@ fn airTrunc(self: *CodeGen, inst: Air.Inst.Index) !void {
164776 .storage = .{ .repeated_elem = mask_val.ip_index },164560 .storage = .{ .repeated_elem = mask_val.ip_index },
164777 } });164561 } });
164778164562
164779 const splat_mcv = try self.genTypedValue(.fromInterned(splat_val));164563 const splat_mcv = try self.lowerValue(.fromInterned(splat_val));
164780 const splat_addr_mcv: MCValue = switch (splat_mcv) {164564 const splat_addr_mcv: MCValue = switch (splat_mcv) {
164781 .memory, .indirect, .load_frame => splat_mcv.address(),164565 .memory, .indirect, .load_frame => splat_mcv.address(),
164782 else => .{ .register = try self.copyToTmpRegister(.usize, splat_mcv.address()) },164566 else => .{ .register = try self.copyToTmpRegister(.usize, splat_mcv.address()) },
...@@ -164975,7 +164759,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void...@@ -164975,7 +164759,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
164975 .mul, .mul_wrap => {},164759 .mul, .mul_wrap => {},
164976 .div_trunc, .div_floor, .div_exact, .rem, .mod => {164760 .div_trunc, .div_floor, .div_exact, .rem, .mod => {
164977 const signed = dst_ty.isSignedInt(zcu);164761 const signed = dst_ty.isSignedInt(zcu);
164978 var callee_buf: ["__udiv?i3".len]u8 = undefined;164762 var sym_buf: ["__udiv?i3".len]u8 = undefined;
164979 const signed_div_floor_state: struct {164763 const signed_div_floor_state: struct {
164980 frame_index: FrameIndex,164764 frame_index: FrameIndex,
164981 state: State,164765 state: State,
...@@ -164994,7 +164778,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void...@@ -164994,7 +164778,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
164994164778
164995 const lhs_mcv = try self.resolveInst(bin_op.lhs);164779 const lhs_mcv = try self.resolveInst(bin_op.lhs);
164996 const mat_lhs_mcv = switch (lhs_mcv) {164780 const mat_lhs_mcv = switch (lhs_mcv) {
164997 .load_symbol => mat_lhs_mcv: {164781 .load_nav, .load_uav, .load_lazy_sym => mat_lhs_mcv: {
164998 // TODO clean this up!164782 // TODO clean this up!
164999 const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address());164783 const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address());
165000 break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };164784 break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
...@@ -165018,7 +164802,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void...@@ -165018,7 +164802,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
165018164802
165019 const rhs_mcv = try self.resolveInst(bin_op.rhs);164803 const rhs_mcv = try self.resolveInst(bin_op.rhs);
165020 const mat_rhs_mcv = switch (rhs_mcv) {164804 const mat_rhs_mcv = switch (rhs_mcv) {
165021 .load_symbol => mat_rhs_mcv: {164805 .load_nav, .load_uav, .load_lazy_sym => mat_rhs_mcv: {
165022 // TODO clean this up!164806 // TODO clean this up!
165023 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());164807 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());
165024 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };164808 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
...@@ -165045,10 +164829,10 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void...@@ -165045,10 +164829,10 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
165045 break :state .{ .frame_index = frame_index, .state = state, .reloc = reloc };164829 break :state .{ .frame_index = frame_index, .state = state, .reloc = reloc };
165046 } else undefined;164830 } else undefined;
165047 const call_mcv = try self.genCall(164831 const call_mcv = try self.genCall(
165048 .{ .lib = .{164832 .{ .extern_func = .{
165049 .return_type = dst_ty.toIntern(),164833 .return_type = dst_ty.toIntern(),
165050 .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() },164834 .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() },
165051 .callee = std.fmt.bufPrint(&callee_buf, "__{s}{s}{c}i3", .{164835 .sym = std.fmt.bufPrint(&sym_buf, "__{s}{s}{c}i3", .{
165052 if (signed) "" else "u",164836 if (signed) "" else "u",
165053 switch (tag) {164837 switch (tag) {
165054 .div_trunc, .div_exact => "div",164838 .div_trunc, .div_exact => "div",
...@@ -165082,10 +164866,10 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void...@@ -165082,10 +164866,10 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
165082 });164866 });
165083 self.performReloc(signed_div_floor_state.reloc);164867 self.performReloc(signed_div_floor_state.reloc);
165084 const dst_mcv = try self.genCall(164868 const dst_mcv = try self.genCall(
165085 .{ .lib = .{164869 .{ .extern_func = .{
165086 .return_type = dst_ty.toIntern(),164870 .return_type = dst_ty.toIntern(),
165087 .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() },164871 .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() },
165088 .callee = std.fmt.bufPrint(&callee_buf, "__div{c}i3", .{164872 .sym = std.fmt.bufPrint(&sym_buf, "__div{c}i3", .{
165089 intCompilerRtAbiName(@intCast(dst_ty.bitSize(zcu))),164873 intCompilerRtAbiName(@intCast(dst_ty.bitSize(zcu))),
165090 }) catch unreachable,164874 }) catch unreachable,
165091 } },164875 } },
...@@ -165119,7 +164903,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void...@@ -165119,7 +164903,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
165119164903
165120 const rhs_mcv = try self.resolveInst(bin_op.rhs);164904 const rhs_mcv = try self.resolveInst(bin_op.rhs);
165121 const mat_rhs_mcv = switch (rhs_mcv) {164905 const mat_rhs_mcv = switch (rhs_mcv) {
165122 .load_symbol => mat_rhs_mcv: {164906 .load_nav, .load_uav, .load_lazy_sym => mat_rhs_mcv: {
165123 // TODO clean this up!164907 // TODO clean this up!
165124 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());164908 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());
165125 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };164909 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
...@@ -165333,10 +165117,10 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -165333,10 +165117,10 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void {
165333 const ptr_c_int = try pt.singleMutPtrType(.c_int);165117 const ptr_c_int = try pt.singleMutPtrType(.c_int);
165334 const overflow = try self.allocTempRegOrMem(.c_int, false);165118 const overflow = try self.allocTempRegOrMem(.c_int, false);
165335165119
165336 const dst_mcv = try self.genCall(.{ .lib = .{165120 const dst_mcv = try self.genCall(.{ .extern_func = .{
165337 .return_type = .i128_type,165121 .return_type = .i128_type,
165338 .param_types = &.{ .i128_type, .i128_type, ptr_c_int.toIntern() },165122 .param_types = &.{ .i128_type, .i128_type, ptr_c_int.toIntern() },
165339 .callee = "__muloti4",165123 .sym = "__muloti4",
165340 } }, &.{ .i128, .i128, ptr_c_int }, &.{165124 } }, &.{ .i128, .i128, ptr_c_int }, &.{
165341 .{ .air_ref = bin_op.lhs },165125 .{ .air_ref = bin_op.lhs },
165342 .{ .air_ref = bin_op.rhs },165126 .{ .air_ref = bin_op.rhs },
...@@ -165351,7 +165135,7 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -165351,7 +165135,7 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void {
165351165135
165352 const lhs_mcv = try self.resolveInst(bin_op.lhs);165136 const lhs_mcv = try self.resolveInst(bin_op.lhs);
165353 const mat_lhs_mcv = switch (lhs_mcv) {165137 const mat_lhs_mcv = switch (lhs_mcv) {
165354 .load_symbol => mat_lhs_mcv: {165138 .load_nav, .load_uav, .load_lazy_sym => mat_lhs_mcv: {
165355 // TODO clean this up!165139 // TODO clean this up!
165356 const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address());165140 const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address());
165357 break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };165141 break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
...@@ -165375,7 +165159,7 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -165375,7 +165159,7 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void {
165375165159
165376 const rhs_mcv = try self.resolveInst(bin_op.rhs);165160 const rhs_mcv = try self.resolveInst(bin_op.rhs);
165377 const mat_rhs_mcv = switch (rhs_mcv) {165161 const mat_rhs_mcv = switch (rhs_mcv) {
165378 .load_symbol => mat_rhs_mcv: {165162 .load_nav, .load_uav, .load_lazy_sym => mat_rhs_mcv: {
165379 // TODO clean this up!165163 // TODO clean this up!
165380 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());165164 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());
165381 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };165165 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
...@@ -165849,10 +165633,10 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -165849,10 +165633,10 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {
165849 .signed => {165633 .signed => {
165850 const ptr_c_int = try pt.singleMutPtrType(.c_int);165634 const ptr_c_int = try pt.singleMutPtrType(.c_int);
165851 const overflow = try self.allocTempRegOrMem(.c_int, false);165635 const overflow = try self.allocTempRegOrMem(.c_int, false);
165852 const result = try self.genCall(.{ .lib = .{165636 const result = try self.genCall(.{ .extern_func = .{
165853 .return_type = .i128_type,165637 .return_type = .i128_type,
165854 .param_types = &.{ .i128_type, .i128_type, ptr_c_int.toIntern() },165638 .param_types = &.{ .i128_type, .i128_type, ptr_c_int.toIntern() },
165855 .callee = "__muloti4",165639 .sym = "__muloti4",
165856 } }, &.{ .i128, .i128, ptr_c_int }, &.{165640 } }, &.{ .i128, .i128, ptr_c_int }, &.{
165857 .{ .air_ref = bin_op.lhs },165641 .{ .air_ref = bin_op.lhs },
165858 .{ .air_ref = bin_op.rhs },165642 .{ .air_ref = bin_op.rhs },
...@@ -165906,7 +165690,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -165906,7 +165690,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {
165906 break :mat_lhs_mcv mat_lhs_mcv;165690 break :mat_lhs_mcv mat_lhs_mcv;
165907 },165691 },
165908 },165692 },
165909 .load_symbol => {165693 .load_nav, .load_uav, .load_lazy_sym => {
165910 // TODO clean this up!165694 // TODO clean this up!
165911 const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address());165695 const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address());
165912 break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };165696 break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
...@@ -165930,7 +165714,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -165930,7 +165714,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {
165930 break :mat_rhs_mcv mat_rhs_mcv;165714 break :mat_rhs_mcv mat_rhs_mcv;
165931 },165715 },
165932 },165716 },
165933 .load_symbol => {165717 .load_nav, .load_uav, .load_lazy_sym => {
165934 // TODO clean this up!165718 // TODO clean this up!
165935 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());165719 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());
165936 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };165720 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
...@@ -166406,7 +166190,7 @@ fn airShlShrBinOp(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -166406,7 +166190,7 @@ fn airShlShrBinOp(self: *CodeGen, inst: Air.Inst.Index) !void {
166406 defer self.register_manager.unlockReg(shift_lock);166190 defer self.register_manager.unlockReg(shift_lock);
166407166191
166408 const mask_ty = try pt.vectorType(.{ .len = 16, .child = .u8_type });166192 const mask_ty = try pt.vectorType(.{ .len = 16, .child = .u8_type });
166409 const mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{166193 const mask_mcv = try self.lowerValue(.fromInterned(try pt.intern(.{ .aggregate = .{
166410 .ty = mask_ty.toIntern(),166194 .ty = mask_ty.toIntern(),
166411 .storage = .{ .elems = &([1]InternPool.Index{166195 .storage = .{ .elems = &([1]InternPool.Index{
166412 (try rhs_ty.childType(zcu).maxIntScalar(pt, .u8)).toIntern(),166196 (try rhs_ty.childType(zcu).maxIntScalar(pt, .u8)).toIntern(),
...@@ -166547,7 +166331,7 @@ fn airShlSat(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -166547,7 +166331,7 @@ fn airShlSat(self: *CodeGen, inst: Air.Inst.Index) !void {
166547 // if lhs is negative, it is min166331 // if lhs is negative, it is min
166548 switch (lhs_ty.intInfo(zcu).signedness) {166332 switch (lhs_ty.intInfo(zcu).signedness) {
166549 .unsigned => {166333 .unsigned => {
166550 const bound_mcv = try self.genTypedValue(try lhs_ty.maxIntScalar(self.pt, lhs_ty));166334 const bound_mcv = try self.lowerValue(try lhs_ty.maxIntScalar(self.pt, lhs_ty));
166551 try self.genCopy(lhs_ty, dst_mcv, bound_mcv, .{});166335 try self.genCopy(lhs_ty, dst_mcv, bound_mcv, .{});
166552 },166336 },
166553 .signed => {166337 .signed => {
...@@ -166556,7 +166340,7 @@ fn airShlSat(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -166556,7 +166340,7 @@ fn airShlSat(self: *CodeGen, inst: Air.Inst.Index) !void {
166556 // we only need the highest bit so shifting the highest part of lhs_mcv166340 // we only need the highest bit so shifting the highest part of lhs_mcv
166557 // is enough to check the signedness. other parts can be skipped here.166341 // is enough to check the signedness. other parts can be skipped here.
166558 var lhs_temp2 = try self.tempInit(lhs_ty, lhs_mcv);166342 var lhs_temp2 = try self.tempInit(lhs_ty, lhs_mcv);
166559 var zero_temp = try self.tempInit(lhs_ty, try self.genTypedValue(try self.pt.intValue(lhs_ty, 0)));166343 var zero_temp = try self.tempInit(lhs_ty, try self.lowerValue(try self.pt.intValue(lhs_ty, 0)));
166560 const sign_cc_temp = lhs_temp2.cmpInts(.lt, &zero_temp, self) catch |err| switch (err) {166344 const sign_cc_temp = lhs_temp2.cmpInts(.lt, &zero_temp, self) catch |err| switch (err) {
166561 error.SelectFailed => unreachable,166345 error.SelectFailed => unreachable,
166562 else => |e| return e,166346 else => |e| return e,
...@@ -166567,13 +166351,13 @@ fn airShlSat(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -166567,13 +166351,13 @@ fn airShlSat(self: *CodeGen, inst: Air.Inst.Index) !void {
166567 try sign_cc_temp.die(self);166351 try sign_cc_temp.die(self);
166568166352
166569 // if it is negative166353 // if it is negative
166570 const min_mcv = try self.genTypedValue(try lhs_ty.minIntScalar(self.pt, lhs_ty));166354 const min_mcv = try self.lowerValue(try lhs_ty.minIntScalar(self.pt, lhs_ty));
166571 try self.genCopy(lhs_ty, dst_mcv, min_mcv, .{});166355 try self.genCopy(lhs_ty, dst_mcv, min_mcv, .{});
166572 const sign_reloc_br = try self.asmJmpReloc(undefined);166356 const sign_reloc_br = try self.asmJmpReloc(undefined);
166573 self.performReloc(sign_reloc_condbr);166357 self.performReloc(sign_reloc_condbr);
166574166358
166575 // if it is positive166359 // if it is positive
166576 const max_mcv = try self.genTypedValue(try lhs_ty.maxIntScalar(self.pt, lhs_ty));166360 const max_mcv = try self.lowerValue(try lhs_ty.maxIntScalar(self.pt, lhs_ty));
166577 try self.genCopy(lhs_ty, dst_mcv, max_mcv, .{});166361 try self.genCopy(lhs_ty, dst_mcv, max_mcv, .{});
166578 self.performReloc(sign_reloc_br);166362 self.performReloc(sign_reloc_br);
166579 },166363 },
...@@ -167294,7 +167078,12 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -167294,7 +167078,12 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void {
167294 }.to64(),167078 }.to64(),
167295 ),167079 ),
167296 },167080 },
167297 .memory, .load_symbol, .load_direct, .load_got => switch (index_mcv) {167081 .memory,
167082 .load_nav,
167083 .load_uav,
167084 .load_lazy_sym,
167085 .load_extern_func,
167086 => switch (index_mcv) {
167298 .immediate => |index_imm| try self.asmMemoryImmediate(167087 .immediate => |index_imm| try self.asmMemoryImmediate(
167299 .{ ._, .bt },167088 .{ ._, .bt },
167300 .{167089 .{
...@@ -167356,11 +167145,15 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -167356,11 +167145,15 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void {
167356 },167145 },
167357 ),167146 ),
167358 .memory,167147 .memory,
167359 .load_symbol,167148 .load_nav,
167360 .load_direct,167149 .lea_nav,
167361 .load_got,167150 .load_uav,
167151 .lea_uav,
167152 .load_lazy_sym,
167153 .lea_lazy_sym,
167154 .load_extern_func,
167155 .lea_extern_func,
167362 => try self.genSetReg(addr_reg, .usize, array_mcv.address(), .{}),167156 => try self.genSetReg(addr_reg, .usize, array_mcv.address(), .{}),
167363 .lea_symbol, .lea_direct => unreachable,
167364 else => return self.fail("TODO airArrayElemVal_val for {s} of {}", .{167157 else => return self.fail("TODO airArrayElemVal_val for {s} of {}", .{
167365 @tagName(array_mcv), array_ty.fmt(pt),167158 @tagName(array_mcv), array_ty.fmt(pt),
167366 }),167159 }),
...@@ -168461,7 +168254,7 @@ fn floatSign(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag, operand: A...@@ -168461,7 +168254,7 @@ fn floatSign(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag, operand: A
168461 .child = (try pt.intType(.signed, scalar_bits)).ip_index,168254 .child = (try pt.intType(.signed, scalar_bits)).ip_index,
168462 });168255 });
168463168256
168464 const sign_mcv = try self.genTypedValue(switch (tag) {168257 const sign_mcv = try self.lowerValue(switch (tag) {
168465 .neg => try vec_ty.minInt(pt, vec_ty),168258 .neg => try vec_ty.minInt(pt, vec_ty),
168466 .abs => try vec_ty.maxInt(pt, vec_ty),168259 .abs => try vec_ty.maxInt(pt, vec_ty),
168467 else => unreachable,168260 else => unreachable,
...@@ -168603,11 +168396,11 @@ fn genRoundLibcall(self: *CodeGen, ty: Type, src_mcv: MCValue, mode: bits.RoundM...@@ -168603,11 +168396,11 @@ fn genRoundLibcall(self: *CodeGen, ty: Type, src_mcv: MCValue, mode: bits.RoundM
168603 if (ty.zigTypeTag(zcu) != .float)168396 if (ty.zigTypeTag(zcu) != .float)
168604 return self.fail("TODO implement genRound for {}", .{ty.fmt(pt)});168397 return self.fail("TODO implement genRound for {}", .{ty.fmt(pt)});
168605168398
168606 var callee_buf: ["__trunc?".len]u8 = undefined;168399 var sym_buf: ["__trunc?".len]u8 = undefined;
168607 return try self.genCall(.{ .lib = .{168400 return try self.genCall(.{ .extern_func = .{
168608 .return_type = ty.toIntern(),168401 .return_type = ty.toIntern(),
168609 .param_types = &.{ty.toIntern()},168402 .param_types = &.{ty.toIntern()},
168610 .callee = std.fmt.bufPrint(&callee_buf, "{s}{s}{s}", .{168403 .sym = std.fmt.bufPrint(&sym_buf, "{s}{s}{s}", .{
168611 floatLibcAbiPrefix(ty),168404 floatLibcAbiPrefix(ty),
168612 switch (mode.direction) {168405 switch (mode.direction) {
168613 .down => "floor",168406 .down => "floor",
...@@ -168880,11 +168673,11 @@ fn airSqrt(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -168880,11 +168673,11 @@ fn airSqrt(self: *CodeGen, inst: Air.Inst.Index) !void {
168880 80, 128 => true,168673 80, 128 => true,
168881 else => unreachable,168674 else => unreachable,
168882 }) {168675 }) {
168883 var callee_buf: ["__sqrt?".len]u8 = undefined;168676 var sym_buf: ["__sqrt?".len]u8 = undefined;
168884 break :result try self.genCall(.{ .lib = .{168677 break :result try self.genCall(.{ .extern_func = .{
168885 .return_type = ty.toIntern(),168678 .return_type = ty.toIntern(),
168886 .param_types = &.{ty.toIntern()},168679 .param_types = &.{ty.toIntern()},
168887 .callee = std.fmt.bufPrint(&callee_buf, "{s}sqrt{s}", .{168680 .sym = std.fmt.bufPrint(&sym_buf, "{s}sqrt{s}", .{
168888 floatLibcAbiPrefix(ty),168681 floatLibcAbiPrefix(ty),
168889 floatLibcAbiSuffix(ty),168682 floatLibcAbiSuffix(ty),
168890 }) catch unreachable,168683 }) catch unreachable,
...@@ -169033,11 +168826,11 @@ fn airSqrt(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -169033,11 +168826,11 @@ fn airSqrt(self: *CodeGen, inst: Air.Inst.Index) !void {
169033fn airUnaryMath(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {168826fn airUnaryMath(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
169034 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;168827 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
169035 const ty = self.typeOf(un_op);168828 const ty = self.typeOf(un_op);
169036 var callee_buf: ["__round?".len]u8 = undefined;168829 var sym_buf: ["__round?".len]u8 = undefined;
169037 const result = try self.genCall(.{ .lib = .{168830 const result = try self.genCall(.{ .extern_func = .{
169038 .return_type = ty.toIntern(),168831 .return_type = ty.toIntern(),
169039 .param_types = &.{ty.toIntern()},168832 .param_types = &.{ty.toIntern()},
169040 .callee = std.fmt.bufPrint(&callee_buf, "{s}{s}{s}", .{168833 .sym = std.fmt.bufPrint(&sym_buf, "{s}{s}{s}", .{
169041 floatLibcAbiPrefix(ty),168834 floatLibcAbiPrefix(ty),
169042 switch (tag) {168835 switch (tag) {
169043 .sin,168836 .sin,
...@@ -169237,19 +169030,19 @@ fn load(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerE...@@ -169237,19 +169030,19 @@ fn load(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerE
169237 .immediate,169030 .immediate,
169238 .register,169031 .register,
169239 .register_offset,169032 .register_offset,
169240 .lea_symbol,
169241 .lea_pcrel,
169242 .lea_direct,
169243 .lea_got,
169244 .lea_frame,169033 .lea_frame,
169034 .lea_nav,
169035 .lea_uav,
169036 .lea_lazy_sym,
169037 .lea_extern_func,
169245 => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref(), .{}),169038 => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref(), .{}),
169246 .memory,169039 .memory,
169247 .indirect,169040 .indirect,
169248 .load_symbol,
169249 .load_pcrel,
169250 .load_direct,
169251 .load_got,
169252 .load_frame,169041 .load_frame,
169042 .load_nav,
169043 .load_uav,
169044 .load_lazy_sym,
169045 .load_extern_func,
169253 => {169046 => {
169254 const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv);169047 const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv);
169255 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);169048 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
...@@ -169457,19 +169250,19 @@ fn store(...@@ -169457,19 +169250,19 @@ fn store(
169457 .immediate,169250 .immediate,
169458 .register,169251 .register,
169459 .register_offset,169252 .register_offset,
169460 .lea_symbol,
169461 .lea_pcrel,
169462 .lea_direct,
169463 .lea_got,
169464 .lea_frame,169253 .lea_frame,
169254 .lea_nav,
169255 .lea_uav,
169256 .lea_lazy_sym,
169257 .lea_extern_func,
169465 => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv, opts),169258 => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv, opts),
169466 .memory,169259 .memory,
169467 .indirect,169260 .indirect,
169468 .load_symbol,
169469 .load_pcrel,
169470 .load_direct,
169471 .load_got,
169472 .load_frame,169261 .load_frame,
169262 .load_nav,
169263 .load_uav,
169264 .load_lazy_sym,
169265 .load_extern_func,
169473 => {169266 => {
169474 const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv);169267 const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv);
169475 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);169268 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
...@@ -169935,18 +169728,18 @@ fn genUnOpMir(self: *CodeGen, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv:...@@ -169935,18 +169728,18 @@ fn genUnOpMir(self: *CodeGen, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv:
169935 .eflags,169728 .eflags,
169936 .register_overflow,169729 .register_overflow,
169937 .register_mask,169730 .register_mask,
169938 .lea_symbol,
169939 .lea_pcrel,
169940 .lea_direct,
169941 .lea_got,
169942 .lea_frame,169731 .lea_frame,
169732 .lea_nav,
169733 .lea_uav,
169734 .lea_lazy_sym,
169735 .lea_extern_func,
169943 .elementwise_args,169736 .elementwise_args,
169944 .reserved_frame,169737 .reserved_frame,
169945 .air_ref,169738 .air_ref,
169946 => unreachable, // unmodifiable destination169739 => unreachable, // unmodifiable destination
169947 .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)),169740 .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)),
169948 .register_pair, .register_triple, .register_quadruple => unreachable, // unimplemented169741 .register_pair, .register_triple, .register_quadruple => unreachable, // unimplemented
169949 .memory, .load_symbol, .load_pcrel, .load_got, .load_direct => {169742 .memory, .load_nav, .load_uav, .load_lazy_sym, .load_extern_func => {
169950 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);169743 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
169951 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);169744 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
169952 defer self.register_manager.unlockReg(addr_reg_lock);169745 defer self.register_manager.unlockReg(addr_reg_lock);
...@@ -170706,7 +170499,7 @@ fn genMulDivBinOp(...@@ -170706,7 +170499,7 @@ fn genMulDivBinOp(
170706 defer for (reg_locks) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock);170499 defer for (reg_locks) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock);
170707170500
170708 const mat_lhs_mcv = switch (lhs_mcv) {170501 const mat_lhs_mcv = switch (lhs_mcv) {
170709 .load_symbol => mat_lhs_mcv: {170502 .load_nav, .load_uav, .load_lazy_sym => mat_lhs_mcv: {
170710 // TODO clean this up!170503 // TODO clean this up!
170711 const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address());170504 const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address());
170712 break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };170505 break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
...@@ -170719,7 +170512,7 @@ fn genMulDivBinOp(...@@ -170719,7 +170512,7 @@ fn genMulDivBinOp(
170719 };170512 };
170720 defer if (mat_lhs_lock) |lock| self.register_manager.unlockReg(lock);170513 defer if (mat_lhs_lock) |lock| self.register_manager.unlockReg(lock);
170721 const mat_rhs_mcv = switch (rhs_mcv) {170514 const mat_rhs_mcv = switch (rhs_mcv) {
170722 .load_symbol => mat_rhs_mcv: {170515 .load_nav, .load_uav, .load_lazy_sym => mat_rhs_mcv: {
170723 // TODO clean this up!170516 // TODO clean this up!
170724 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());170517 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());
170725 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };170518 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
...@@ -170887,7 +170680,7 @@ fn genMulDivBinOp(...@@ -170887,7 +170680,7 @@ fn genMulDivBinOp(
170887 .is_const = true,170680 .is_const = true,
170888 },170681 },
170889 });170682 });
170890 _ = try self.genCall(.{ .lib = .{170683 _ = try self.genCall(.{ .extern_func = .{
170891 .return_type = .void_type,170684 .return_type = .void_type,
170892 .param_types = &.{170685 .param_types = &.{
170893 manyptr_u32_ty.toIntern(),170686 manyptr_u32_ty.toIntern(),
...@@ -170895,7 +170688,7 @@ fn genMulDivBinOp(...@@ -170895,7 +170688,7 @@ fn genMulDivBinOp(
170895 manyptr_const_u32_ty.toIntern(),170688 manyptr_const_u32_ty.toIntern(),
170896 .usize_type,170689 .usize_type,
170897 },170690 },
170898 .callee = switch (tag) {170691 .sym = switch (tag) {
170899 .div_trunc,170692 .div_trunc,
170900 .div_floor,170693 .div_floor,
170901 .div_exact,170694 .div_exact,
...@@ -171118,8 +170911,8 @@ fn genBinOp(...@@ -171118,8 +170911,8 @@ fn genBinOp(
171118 .rem, .mod => {},170911 .rem, .mod => {},
171119 else => if (!type_needs_libcall) break :libcall,170912 else => if (!type_needs_libcall) break :libcall,
171120 }170913 }
171121 var callee_buf: ["__mod?f3".len]u8 = undefined;170914 var sym_buf: ["__mod?f3".len]u8 = undefined;
171122 const callee = switch (air_tag) {170915 const sym = switch (air_tag) {
171123 .add,170916 .add,
171124 .sub,170917 .sub,
171125 .mul,170918 .mul,
...@@ -171127,11 +170920,11 @@ fn genBinOp(...@@ -171127,11 +170920,11 @@ fn genBinOp(
171127 .div_trunc,170920 .div_trunc,
171128 .div_floor,170921 .div_floor,
171129 .div_exact,170922 .div_exact,
171130 => std.fmt.bufPrint(&callee_buf, "__{s}{c}f3", .{170923 => std.fmt.bufPrint(&sym_buf, "__{s}{c}f3", .{
171131 @tagName(air_tag)[0..3],170924 @tagName(air_tag)[0..3],
171132 floatCompilerRtAbiName(float_bits),170925 floatCompilerRtAbiName(float_bits),
171133 }),170926 }),
171134 .rem, .mod, .min, .max => std.fmt.bufPrint(&callee_buf, "{s}f{s}{s}", .{170927 .rem, .mod, .min, .max => std.fmt.bufPrint(&sym_buf, "{s}f{s}{s}", .{
171135 floatLibcAbiPrefix(lhs_ty),170928 floatLibcAbiPrefix(lhs_ty),
171136 switch (air_tag) {170929 switch (air_tag) {
171137 .rem, .mod => "mod",170930 .rem, .mod => "mod",
...@@ -171145,22 +170938,22 @@ fn genBinOp(...@@ -171145,22 +170938,22 @@ fn genBinOp(
171145 @tagName(air_tag), lhs_ty.fmt(pt),170938 @tagName(air_tag), lhs_ty.fmt(pt),
171146 }),170939 }),
171147 } catch unreachable;170940 } catch unreachable;
171148 const result = try self.genCall(.{ .lib = .{170941 const result = try self.genCall(.{ .extern_func = .{
171149 .return_type = lhs_ty.toIntern(),170942 .return_type = lhs_ty.toIntern(),
171150 .param_types = &.{ lhs_ty.toIntern(), rhs_ty.toIntern() },170943 .param_types = &.{ lhs_ty.toIntern(), rhs_ty.toIntern() },
171151 .callee = callee,170944 .sym = sym,
171152 } }, &.{ lhs_ty, rhs_ty }, &.{ .{ .air_ref = lhs_air }, .{ .air_ref = rhs_air } }, .{});170945 } }, &.{ lhs_ty, rhs_ty }, &.{ .{ .air_ref = lhs_air }, .{ .air_ref = rhs_air } }, .{});
171153 return switch (air_tag) {170946 return switch (air_tag) {
171154 .mod => result: {170947 .mod => result: {
171155 const adjusted: MCValue = if (type_needs_libcall) adjusted: {170948 const adjusted: MCValue = if (type_needs_libcall) adjusted: {
171156 var add_callee_buf: ["__add?f3".len]u8 = undefined;170949 var add_sym_buf: ["__add?f3".len]u8 = undefined;
171157 break :adjusted try self.genCall(.{ .lib = .{170950 break :adjusted try self.genCall(.{ .extern_func = .{
171158 .return_type = lhs_ty.toIntern(),170951 .return_type = lhs_ty.toIntern(),
171159 .param_types = &.{170952 .param_types = &.{
171160 lhs_ty.toIntern(),170953 lhs_ty.toIntern(),
171161 rhs_ty.toIntern(),170954 rhs_ty.toIntern(),
171162 },170955 },
171163 .callee = std.fmt.bufPrint(&add_callee_buf, "__add{c}f3", .{170956 .sym = std.fmt.bufPrint(&add_sym_buf, "__add{c}f3", .{
171164 floatCompilerRtAbiName(float_bits),170957 floatCompilerRtAbiName(float_bits),
171165 }) catch unreachable,170958 }) catch unreachable,
171166 } }, &.{ lhs_ty, rhs_ty }, &.{ result, .{ .air_ref = rhs_air } }, .{});170959 } }, &.{ lhs_ty, rhs_ty }, &.{ result, .{ .air_ref = rhs_air } }, .{});
...@@ -171259,10 +171052,10 @@ fn genBinOp(...@@ -171259,10 +171052,10 @@ fn genBinOp(
171259 }),171052 }),
171260 else => unreachable,171053 else => unreachable,
171261 };171054 };
171262 break :result try self.genCall(.{ .lib = .{171055 break :result try self.genCall(.{ .extern_func = .{
171263 .return_type = lhs_ty.toIntern(),171056 .return_type = lhs_ty.toIntern(),
171264 .param_types = &.{ lhs_ty.toIntern(), rhs_ty.toIntern() },171057 .param_types = &.{ lhs_ty.toIntern(), rhs_ty.toIntern() },
171265 .callee = callee,171058 .sym = sym,
171266 } }, &.{ lhs_ty, rhs_ty }, &.{ adjusted, .{ .air_ref = rhs_air } }, .{});171059 } }, &.{ lhs_ty, rhs_ty }, &.{ adjusted, .{ .air_ref = rhs_air } }, .{});
171267 },171060 },
171268 .div_trunc, .div_floor => try self.genRoundLibcall(lhs_ty, result, .{171061 .div_trunc, .div_floor => try self.genRoundLibcall(lhs_ty, result, .{
...@@ -171545,13 +171338,15 @@ fn genBinOp(...@@ -171545,13 +171338,15 @@ fn genBinOp(
171545 .immediate,171338 .immediate,
171546 .eflags,171339 .eflags,
171547 .register_offset,171340 .register_offset,
171548 .load_symbol,
171549 .lea_symbol,
171550 .load_direct,
171551 .lea_direct,
171552 .load_got,
171553 .lea_got,
171554 .lea_frame,171341 .lea_frame,
171342 .load_nav,
171343 .lea_nav,
171344 .load_uav,
171345 .lea_uav,
171346 .load_lazy_sym,
171347 .lea_lazy_sym,
171348 .load_extern_func,
171349 .lea_extern_func,
171555 => true,171350 => true,
171556 .memory => |addr| std.math.cast(i32, @as(i64, @bitCast(addr))) == null,171351 .memory => |addr| std.math.cast(i32, @as(i64, @bitCast(addr))) == null,
171557 else => false,171352 else => false,
...@@ -171604,15 +171399,15 @@ fn genBinOp(...@@ -171604,15 +171399,15 @@ fn genBinOp(
171604 .register_offset,171399 .register_offset,
171605 .register_overflow,171400 .register_overflow,
171606 .register_mask,171401 .register_mask,
171607 .load_symbol,
171608 .lea_symbol,
171609 .load_pcrel,
171610 .lea_pcrel,
171611 .load_direct,
171612 .lea_direct,
171613 .load_got,
171614 .lea_got,
171615 .lea_frame,171402 .lea_frame,
171403 .load_nav,
171404 .lea_nav,
171405 .load_uav,
171406 .lea_uav,
171407 .load_lazy_sym,
171408 .lea_lazy_sym,
171409 .load_extern_func,
171410 .lea_extern_func,
171616 .elementwise_args,171411 .elementwise_args,
171617 .reserved_frame,171412 .reserved_frame,
171618 .air_ref,171413 .air_ref,
...@@ -172710,7 +172505,7 @@ fn genBinOp(...@@ -172710,7 +172505,7 @@ fn genBinOp(
172710 .cmp_neq,172505 .cmp_neq,
172711 => {172506 => {
172712 const unsigned_ty = try lhs_ty.toUnsigned(pt);172507 const unsigned_ty = try lhs_ty.toUnsigned(pt);
172713 const not_mcv = try self.genTypedValue(try unsigned_ty.maxInt(pt, unsigned_ty));172508 const not_mcv = try self.lowerValue(try unsigned_ty.maxInt(pt, unsigned_ty));
172714 const not_mem: Memory = if (not_mcv.isBase())172509 const not_mem: Memory = if (not_mcv.isBase())
172715 try not_mcv.mem(self, .{ .size = .fromSize(abi_size) })172510 try not_mcv.mem(self, .{ .size = .fromSize(abi_size) })
172716 else172511 else
...@@ -172792,11 +172587,11 @@ fn genBinOpMir(...@@ -172792,11 +172587,11 @@ fn genBinOpMir(
172792 .eflags,172587 .eflags,
172793 .register_overflow,172588 .register_overflow,
172794 .register_mask,172589 .register_mask,
172795 .lea_direct,
172796 .lea_got,
172797 .lea_frame,172590 .lea_frame,
172798 .lea_symbol,172591 .lea_nav,
172799 .lea_pcrel,172592 .lea_uav,
172593 .lea_lazy_sym,
172594 .lea_extern_func,
172800 .elementwise_args,172595 .elementwise_args,
172801 .reserved_frame,172596 .reserved_frame,
172802 .air_ref,172597 .air_ref,
...@@ -172886,16 +172681,16 @@ fn genBinOpMir(...@@ -172886,16 +172681,16 @@ fn genBinOpMir(
172886 .register_offset,172681 .register_offset,
172887 .memory,172682 .memory,
172888 .indirect,172683 .indirect,
172889 .load_symbol,
172890 .lea_symbol,
172891 .load_pcrel,
172892 .lea_pcrel,
172893 .load_direct,
172894 .lea_direct,
172895 .load_got,
172896 .lea_got,
172897 .load_frame,172684 .load_frame,
172898 .lea_frame,172685 .lea_frame,
172686 .load_nav,
172687 .lea_nav,
172688 .load_uav,
172689 .lea_uav,
172690 .load_lazy_sym,
172691 .lea_lazy_sym,
172692 .load_extern_func,
172693 .lea_extern_func,
172899 => {172694 => {
172900 direct: {172695 direct: {
172901 try self.asmRegisterMemory(mir_limb_tag, dst_alias, switch (src_mcv) {172696 try self.asmRegisterMemory(mir_limb_tag, dst_alias, switch (src_mcv) {
...@@ -172928,10 +172723,11 @@ fn genBinOpMir(...@@ -172928,10 +172723,11 @@ fn genBinOpMir(
172928 switch (src_mcv) {172723 switch (src_mcv) {
172929 .eflags,172724 .eflags,
172930 .register_offset,172725 .register_offset,
172931 .lea_symbol,
172932 .lea_direct,
172933 .lea_got,
172934 .lea_frame,172726 .lea_frame,
172727 .lea_nav,
172728 .lea_uav,
172729 .lea_lazy_sym,
172730 .lea_extern_func,
172935 => {172731 => {
172936 assert(off == 0);172732 assert(off == 0);
172937 const reg = try self.copyToTmpRegister(ty, src_mcv);172733 const reg = try self.copyToTmpRegister(ty, src_mcv);
...@@ -172943,9 +172739,10 @@ fn genBinOpMir(...@@ -172943,9 +172739,10 @@ fn genBinOpMir(
172943 );172739 );
172944 },172740 },
172945 .memory,172741 .memory,
172946 .load_symbol,172742 .load_nav,
172947 .load_direct,172743 .load_uav,
172948 .load_got,172744 .load_lazy_sym,
172745 .load_extern_func,
172949 => {172746 => {
172950 const ptr_ty = try pt.singleConstPtrType(ty);172747 const ptr_ty = try pt.singleConstPtrType(ty);
172951 const addr_reg = try self.copyToTmpRegister(ptr_ty, src_mcv.address());172748 const addr_reg = try self.copyToTmpRegister(ptr_ty, src_mcv.address());
...@@ -172965,13 +172762,20 @@ fn genBinOpMir(...@@ -172965,13 +172762,20 @@ fn genBinOpMir(
172965 }172762 }
172966 }172763 }
172967 },172764 },
172968 .memory, .indirect, .load_symbol, .load_pcrel, .load_got, .load_direct, .load_frame => {172765 .memory,
172766 .indirect,
172767 .load_frame,
172768 .load_nav,
172769 .load_uav,
172770 .load_lazy_sym,
172771 .load_extern_func,
172772 => {
172969 const OpInfo = ?struct { addr_reg: Register, addr_lock: RegisterLock };172773 const OpInfo = ?struct { addr_reg: Register, addr_lock: RegisterLock };
172970 const limb_abi_size: u32 = @min(abi_size, 8);172774 const limb_abi_size: u32 = @min(abi_size, 8);
172971172775
172972 const dst_info: OpInfo = switch (dst_mcv) {172776 const dst_info: OpInfo = switch (dst_mcv) {
172973 else => unreachable,172777 else => unreachable,
172974 .memory, .load_symbol, .load_got, .load_direct => dst: {172778 .memory, .load_nav, .load_uav, .load_lazy_sym, .load_extern_func => dst: {
172975 const dst_addr_reg =172779 const dst_addr_reg =
172976 (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();172780 (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();
172977 const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg);172781 const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg);
...@@ -173007,19 +172811,24 @@ fn genBinOpMir(...@@ -173007,19 +172811,24 @@ fn genBinOpMir(
173007 .register_quadruple,172811 .register_quadruple,
173008 .register_offset,172812 .register_offset,
173009 .indirect,172813 .indirect,
173010 .lea_direct,
173011 .lea_got,
173012 .load_frame,172814 .load_frame,
173013 .lea_frame,172815 .lea_frame,
173014 .lea_symbol,172816 .lea_nav,
173015 .lea_pcrel,172817 .lea_uav,
172818 .lea_lazy_sym,
172819 .lea_extern_func,
173016 => null,172820 => null,
173017 .memory, .load_symbol, .load_pcrel, .load_got, .load_direct => src: {172821 .memory,
172822 .load_nav,
172823 .load_uav,
172824 .load_lazy_sym,
172825 .load_extern_func,
172826 => src: {
173018 switch (resolved_src_mcv) {172827 switch (resolved_src_mcv) {
173019 .memory => |addr| if (std.math.cast(i32, @as(i64, @bitCast(addr))) != null and172828 .memory => |addr| if (std.math.cast(i32, @as(i64, @bitCast(addr))) != null and
173020 std.math.cast(i32, @as(i64, @bitCast(addr)) + abi_size - limb_abi_size) != null)172829 std.math.cast(i32, @as(i64, @bitCast(addr)) + abi_size - limb_abi_size) != null)
173021 break :src null,172830 break :src null,
173022 .load_symbol, .load_got, .load_direct => {},172831 .load_nav, .load_uav, .load_lazy_sym, .load_extern_func => {},
173023 else => unreachable,172832 else => unreachable,
173024 }172833 }
173025172834
...@@ -173059,9 +172868,10 @@ fn genBinOpMir(...@@ -173059,9 +172868,10 @@ fn genBinOpMir(
173059 };172868 };
173060 const dst_limb_mem: Memory = switch (dst_mcv) {172869 const dst_limb_mem: Memory = switch (dst_mcv) {
173061 .memory,172870 .memory,
173062 .load_symbol,172871 .load_nav,
173063 .load_got,172872 .load_uav,
173064 .load_direct,172873 .load_lazy_sym,
172874 .load_extern_func,
173065 => .{172875 => .{
173066 .base = .{ .reg = dst_info.?.addr_reg },172876 .base = .{ .reg = dst_info.?.addr_reg },
173067 .mod = .{ .rm = .{172877 .mod = .{ .rm = .{
...@@ -173151,16 +172961,16 @@ fn genBinOpMir(...@@ -173151,16 +172961,16 @@ fn genBinOpMir(
173151 .eflags,172961 .eflags,
173152 .memory,172962 .memory,
173153 .indirect,172963 .indirect,
173154 .load_symbol,
173155 .lea_symbol,
173156 .load_pcrel,
173157 .lea_pcrel,
173158 .load_direct,
173159 .lea_direct,
173160 .load_got,
173161 .lea_got,
173162 .load_frame,172964 .load_frame,
173163 .lea_frame,172965 .lea_frame,
172966 .load_nav,
172967 .lea_nav,
172968 .load_uav,
172969 .lea_uav,
172970 .load_lazy_sym,
172971 .lea_lazy_sym,
172972 .load_extern_func,
172973 .lea_extern_func,
173164 => {172974 => {
173165 const src_limb_mcv: MCValue = if (src_info) |info| .{172975 const src_limb_mcv: MCValue = if (src_info) |info| .{
173166 .indirect = .{ .reg = info.addr_reg, .off = off },172976 .indirect = .{ .reg = info.addr_reg, .off = off },
...@@ -173170,10 +172980,11 @@ fn genBinOpMir(...@@ -173170,10 +172980,11 @@ fn genBinOpMir(
173170 },172980 },
173171 .eflags,172981 .eflags,
173172 .register_offset,172982 .register_offset,
173173 .lea_symbol,
173174 .lea_direct,
173175 .lea_got,
173176 .lea_frame,172983 .lea_frame,
172984 .lea_nav,
172985 .lea_uav,
172986 .lea_lazy_sym,
172987 .lea_extern_func,
173177 => switch (limb_i) {172988 => switch (limb_i) {
173178 0 => resolved_src_mcv,172989 0 => resolved_src_mcv,
173179 else => .{ .immediate = 0 },172990 else => .{ .immediate = 0 },
...@@ -173221,11 +173032,11 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv...@@ -173221,11 +173032,11 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
173221 .register_offset,173032 .register_offset,
173222 .register_overflow,173033 .register_overflow,
173223 .register_mask,173034 .register_mask,
173224 .lea_symbol,
173225 .lea_pcrel,
173226 .lea_direct,
173227 .lea_got,
173228 .lea_frame,173035 .lea_frame,
173036 .lea_nav,
173037 .lea_uav,
173038 .lea_lazy_sym,
173039 .lea_extern_func,
173229 .elementwise_args,173040 .elementwise_args,
173230 .reserved_frame,173041 .reserved_frame,
173231 .air_ref,173042 .air_ref,
...@@ -173283,15 +173094,15 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv...@@ -173283,15 +173094,15 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
173283 },173094 },
173284 .register_offset,173095 .register_offset,
173285 .eflags,173096 .eflags,
173286 .load_symbol,
173287 .lea_symbol,
173288 .load_pcrel,
173289 .lea_pcrel,
173290 .load_direct,
173291 .lea_direct,
173292 .load_got,
173293 .lea_got,
173294 .lea_frame,173097 .lea_frame,
173098 .load_nav,
173099 .lea_nav,
173100 .load_uav,
173101 .lea_uav,
173102 .load_lazy_sym,
173103 .lea_lazy_sym,
173104 .load_extern_func,
173105 .lea_extern_func,
173295 => {173106 => {
173296 const src_reg = try self.copyToTmpRegister(dst_ty, resolved_src_mcv);173107 const src_reg = try self.copyToTmpRegister(dst_ty, resolved_src_mcv);
173297 switch (abi_size) {173108 switch (abi_size) {
...@@ -173346,7 +173157,14 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv...@@ -173346,7 +173157,14 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
173346 }173157 }
173347 },173158 },
173348 .register_pair, .register_triple, .register_quadruple => unreachable, // unimplemented173159 .register_pair, .register_triple, .register_quadruple => unreachable, // unimplemented
173349 .memory, .indirect, .load_symbol, .load_pcrel, .load_direct, .load_got, .load_frame => {173160 .memory,
173161 .indirect,
173162 .load_frame,
173163 .load_nav,
173164 .load_uav,
173165 .load_lazy_sym,
173166 .load_extern_func,
173167 => {
173350 const tmp_reg = try self.copyToTmpRegister(dst_ty, dst_mcv);173168 const tmp_reg = try self.copyToTmpRegister(dst_ty, dst_mcv);
173351 const tmp_mcv = MCValue{ .register = tmp_reg };173169 const tmp_mcv = MCValue{ .register = tmp_reg };
173352 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);173170 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
...@@ -173359,16 +173177,14 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv...@@ -173359,16 +173177,14 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
173359}173177}
173360173178
173361fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {173179fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {
173362 const pt = self.pt;173180 const zcu = self.pt.zcu;
173363 const zcu = pt.zcu;173181 const arg_index = for (self.args, 0..) |arg, arg_index| {
173364 // skip zero-bit arguments as they don't have a corresponding arg instruction173182 if (arg != .none) break arg_index;
173365 var arg_index = self.arg_index;173183 } else unreachable;
173366 while (self.args[arg_index] == .none) arg_index += 1;173184 const src_mcv = self.args[arg_index];
173367 self.arg_index = arg_index + 1;173185 self.args = self.args[arg_index + 1 ..];
173368173186 const result: MCValue = if (self.mod.strip and self.liveness.isUnused(inst)) .unreach else result: {
173369 const result: MCValue = if (self.debug_output == .none and self.liveness.isUnused(inst)) .unreach else result: {
173370 const arg_ty = self.typeOfIndex(inst);173187 const arg_ty = self.typeOfIndex(inst);
173371 const src_mcv = self.args[arg_index];
173372 switch (src_mcv) {173188 switch (src_mcv) {
173373 .register, .register_pair, .load_frame => {173189 .register, .register_pair, .load_frame => {
173374 for (src_mcv.getRegs()) |reg| self.register_manager.getRegAssumeFree(reg, inst);173190 for (src_mcv.getRegs()) |reg| self.register_manager.getRegAssumeFree(reg, inst);
...@@ -173467,68 +173283,115 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -173467,68 +173283,115 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {
173467 return self.finishAir(inst, result, .{ .none, .none, .none });173283 return self.finishAir(inst, result, .{ .none, .none, .none });
173468}173284}
173469173285
173470fn airDbgVarArgs(self: *CodeGen) !void {173286fn genLocalDebugInfo(cg: *CodeGen, air_tag: Air.Inst.Tag, ty: Type, mcv: MCValue) !void {
173471 if (self.debug_output == .none) return;173287 assert(!cg.mod.strip);
173472 if (!self.pt.zcu.typeToFunc(self.fn_type).?.is_var_args) return;173288 _ = switch (air_tag) {
173473 try self.asmPseudo(.pseudo_dbg_var_args_none);
173474}
173475
173476fn genLocalDebugInfo(
173477 self: *CodeGen,
173478 inst: Air.Inst.Index,
173479 mcv: MCValue,
173480) !void {
173481 if (self.debug_output == .none) return;
173482 switch (self.air.instructions.items(.tag)[@intFromEnum(inst)]) {
173483 else => unreachable,173289 else => unreachable,
173484 .arg, .dbg_arg_inline, .dbg_var_val => |tag| {173290 .arg, .dbg_var_val, .dbg_arg_inline => switch (mcv) {
173485 switch (mcv) {173291 .none, .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,
173486 .none => try self.asmAir(.dbg_local, inst),173292 .immediate => |imm| if (std.math.cast(u32, imm)) |small| try cg.addInst(.{
173487 .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,173293 .tag = .pseudo,
173488 .immediate => |imm| try self.asmAirImmediate(.dbg_local, inst, .u(imm)),173294 .ops = switch (air_tag) {
173489 .lea_frame => |frame_addr| try self.asmAirFrameAddress(.dbg_local, inst, frame_addr),173295 else => unreachable,
173490 .lea_symbol => |sym_off| try self.asmAirImmediate(.dbg_local, inst, .rel(sym_off)),173296 .arg, .dbg_arg_inline => .pseudo_dbg_arg_i_u,
173491 else => {173297 .dbg_var_val => .pseudo_dbg_var_i_u,
173492 const ty = switch (tag) {
173493 else => unreachable,
173494 .arg => self.typeOfIndex(inst),
173495 .dbg_arg_inline, .dbg_var_val => self.typeOf(
173496 self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op.operand,
173497 ),
173498 };
173499 const frame_index = try self.allocFrameIndex(.initSpill(ty, self.pt.zcu));
173500 try self.genSetMem(.{ .frame = frame_index }, 0, ty, mcv, .{});
173501 try self.asmAirMemory(.dbg_local, inst, .{
173502 .base = .{ .frame = frame_index },
173503 .mod = .{ .rm = .{ .size = .qword } },
173504 });
173505 },173298 },
173506 }173299 .data = .{ .i = .{ .i = small } },
173300 }) else try cg.addInst(.{
173301 .tag = .pseudo,
173302 .ops = switch (air_tag) {
173303 else => unreachable,
173304 .arg, .dbg_arg_inline => .pseudo_dbg_arg_i_64,
173305 .dbg_var_val => .pseudo_dbg_var_i_64,
173306 },
173307 .data = .{ .i64 = imm },
173308 }),
173309 .lea_frame => |frame_addr| try cg.addInst(.{
173310 .tag = .pseudo,
173311 .ops = switch (air_tag) {
173312 else => unreachable,
173313 .arg, .dbg_arg_inline => .pseudo_dbg_arg_fa,
173314 .dbg_var_val => .pseudo_dbg_var_fa,
173315 },
173316 .data = .{ .fa = frame_addr },
173317 }),
173318 else => {
173319 const frame_index = try cg.allocFrameIndex(.initSpill(ty, cg.pt.zcu));
173320 try cg.genSetMem(.{ .frame = frame_index }, 0, ty, mcv, .{});
173321 _ = try cg.addInst(.{
173322 .tag = .pseudo,
173323 .ops = switch (air_tag) {
173324 else => unreachable,
173325 .arg, .dbg_arg_inline => .pseudo_dbg_arg_m,
173326 .dbg_var_val => .pseudo_dbg_var_m,
173327 },
173328 .data = .{ .x = .{
173329 .payload = try cg.addExtra(Mir.Memory.encode(.{
173330 .base = .{ .frame = frame_index },
173331 .mod = .{ .rm = .{ .size = .qword } },
173332 })),
173333 } },
173334 });
173335 },
173507 },173336 },
173508 .dbg_var_ptr => switch (mcv) {173337 .dbg_var_ptr => switch (mcv) {
173509 else => unreachable,173338 else => unreachable,
173510 .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,173339 .none, .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,
173511 .lea_frame => |frame_addr| try self.asmAirMemory(.dbg_local, inst, .{173340 .lea_frame => |frame_addr| try cg.addInst(.{
173512 .base = .{ .frame = frame_addr.index },173341 .tag = .pseudo,
173513 .mod = .{ .rm = .{173342 .ops = .pseudo_dbg_var_m,
173514 .size = .qword,173343 .data = .{ .x = .{
173515 .disp = frame_addr.off,173344 .payload = try cg.addExtra(Mir.Memory.encode(.{
173345 .base = .{ .frame = frame_addr.index },
173346 .mod = .{ .rm = .{
173347 .size = .qword,
173348 .disp = frame_addr.off,
173349 } },
173350 })),
173516 } },173351 } },
173517 }),173352 }),
173518 // debug info should explicitly ignore pcrel requirements173353 .lea_nav => |nav| try cg.addInst(.{
173519 .lea_symbol, .lea_pcrel => |sym_off| try self.asmAirMemory(.dbg_local, inst, .{173354 .tag = .pseudo,
173520 .base = .{ .reloc = sym_off.sym_index },173355 .ops = .pseudo_dbg_var_m,
173521 .mod = .{ .rm = .{173356 .data = .{ .x = .{
173522 .size = .qword,173357 .payload = try cg.addExtra(Mir.Memory.encode(.{
173523 .disp = sym_off.off,173358 .base = .{ .nav = nav },
173359 .mod = .{ .rm = .{ .size = .qword } },
173360 })),
173361 } },
173362 }),
173363 .lea_uav => |uav| try cg.addInst(.{
173364 .tag = .pseudo,
173365 .ops = .pseudo_dbg_var_m,
173366 .data = .{ .x = .{
173367 .payload = try cg.addExtra(Mir.Memory.encode(.{
173368 .base = .{ .uav = uav },
173369 .mod = .{ .rm = .{ .size = .qword } },
173370 })),
173524 } },173371 } },
173525 }),173372 }),
173526 .lea_direct, .lea_got => |sym_index| try self.asmAirMemory(.dbg_local, inst, .{173373 .lea_lazy_sym => |lazy_sym| try cg.addInst(.{
173527 .base = .{ .reloc = sym_index },173374 .tag = .pseudo,
173528 .mod = .{ .rm = .{ .size = .qword } },173375 .ops = .pseudo_dbg_var_m,
173376 .data = .{ .x = .{
173377 .payload = try cg.addExtra(Mir.Memory.encode(.{
173378 .base = .{ .lazy_sym = lazy_sym },
173379 .mod = .{ .rm = .{ .size = .qword } },
173380 })),
173381 } },
173382 }),
173383 .lea_extern_func => |extern_func| try cg.addInst(.{
173384 .tag = .pseudo,
173385 .ops = .pseudo_dbg_var_m,
173386 .data = .{ .x = .{
173387 .payload = try cg.addExtra(Mir.Memory.encode(.{
173388 .base = .{ .extern_func = extern_func },
173389 .mod = .{ .rm = .{ .size = .qword } },
173390 })),
173391 } },
173529 }),173392 }),
173530 },173393 },
173531 }173394 };
173532}173395}
173533173396
173534fn airRetAddr(self: *CodeGen, inst: Air.Inst.Index) !void {173397fn airRetAddr(self: *CodeGen, inst: Air.Inst.Index) !void {
...@@ -173552,8 +173415,8 @@ fn airCall(self: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -173552,8 +173415,8 @@ fn airCall(self: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
173552 @ptrCast(self.air.extra.items[extra.end..][0..extra.data.args_len]);173415 @ptrCast(self.air.extra.items[extra.end..][0..extra.data.args_len]);
173553173416
173554 const ExpectedContents = extern struct {173417 const ExpectedContents = extern struct {
173555 tys: [16][@sizeOf(Type)]u8 align(@alignOf(Type)),173418 tys: [32][@sizeOf(Type)]u8 align(@alignOf(Type)),
173556 vals: [16][@sizeOf(MCValue)]u8 align(@alignOf(MCValue)),173419 vals: [32][@sizeOf(MCValue)]u8 align(@alignOf(MCValue)),
173557 };173420 };
173558 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =173421 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =
173559 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);173422 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
...@@ -173579,11 +173442,10 @@ fn airCall(self: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -173579,11 +173442,10 @@ fn airCall(self: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
173579173442
173580fn genCall(self: *CodeGen, info: union(enum) {173443fn genCall(self: *CodeGen, info: union(enum) {
173581 air: Air.Inst.Ref,173444 air: Air.Inst.Ref,
173582 lib: struct {173445 extern_func: struct {
173583 return_type: InternPool.Index,173446 return_type: InternPool.Index,
173584 param_types: []const InternPool.Index,173447 param_types: []const InternPool.Index,
173585 lib: ?[]const u8 = null,173448 sym: []const u8,
173586 callee: []const u8,
173587 },173449 },
173588}, arg_types: []const Type, args: []const MCValue, opts: CopyOptions) !MCValue {173450}, arg_types: []const Type, args: []const MCValue, opts: CopyOptions) !MCValue {
173589 const pt = self.pt;173451 const pt = self.pt;
...@@ -173599,18 +173461,18 @@ fn genCall(self: *CodeGen, info: union(enum) {...@@ -173599,18 +173461,18 @@ fn genCall(self: *CodeGen, info: union(enum) {
173599 else => unreachable,173461 else => unreachable,
173600 };173462 };
173601 },173463 },
173602 .lib => |lib| try pt.funcType(.{173464 .extern_func => |extern_func| try pt.funcType(.{
173603 .param_types = lib.param_types,173465 .param_types = extern_func.param_types,
173604 .return_type = lib.return_type,173466 .return_type = extern_func.return_type,
173605 .cc = self.target.cCallingConvention().?,173467 .cc = self.target.cCallingConvention().?,
173606 }),173468 }),
173607 };173469 };
173608 const fn_info = zcu.typeToFunc(fn_ty).?;173470 const fn_info = zcu.typeToFunc(fn_ty).?;
173609173471
173610 const ExpectedContents = extern struct {173472 const ExpectedContents = extern struct {
173611 var_args: [16][@sizeOf(Type)]u8 align(@alignOf(Type)),173473 var_args: [32][@sizeOf(Type)]u8 align(@alignOf(Type)),
173612 frame_indices: [16]FrameIndex,173474 frame_indices: [32]FrameIndex,
173613 reg_locks: [16][@sizeOf(?RegisterLock)]u8 align(@alignOf(?RegisterLock)),173475 reg_locks: [32][@sizeOf(?RegisterLock)]u8 align(@alignOf(?RegisterLock)),
173614 };173476 };
173615 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =173477 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =
173616 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);173478 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
...@@ -173830,52 +173692,9 @@ fn genCall(self: *CodeGen, info: union(enum) {...@@ -173830,52 +173692,9 @@ fn genCall(self: *CodeGen, info: union(enum) {
173830 else => func_key,173692 else => func_key,
173831 } else func_key,173693 } else func_key,
173832 }) {173694 }) {
173833 .func => |func| {173695 else => unreachable,
173834 if (self.bin_file.cast(.elf)) |elf_file| {173696 .func => |func| try self.asmImmediate(.{ ._, .call }, .{ .nav = .{ .index = func.owner_nav } }),
173835 const zo = elf_file.zigObjectPtr().?;173697 .@"extern" => |@"extern"| try self.asmImmediate(.{ ._, .call }, .{ .nav = .{ .index = @"extern".owner_nav } }),
173836 const sym_index = try zo.getOrCreateMetadataForNav(zcu, func.owner_nav);
173837 try self.asmImmediate(.{ ._, .call }, .rel(.{ .sym_index = sym_index }));
173838 } else if (self.bin_file.cast(.coff)) |coff_file| {
173839 const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav);
173840 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
173841 const scratch_reg = abi.getCAbiLinkerScratchReg(fn_info.cc);
173842 try self.genSetReg(scratch_reg, .usize, .{ .lea_got = sym_index }, .{});
173843 try self.asmRegister(.{ ._, .call }, scratch_reg);
173844 } else if (self.bin_file.cast(.macho)) |macho_file| {
173845 const zo = macho_file.getZigObject().?;
173846 const sym_index = try zo.getOrCreateMetadataForNav(macho_file, func.owner_nav);
173847 const sym = zo.symbols.items[sym_index];
173848 try self.asmImmediate(.{ ._, .call }, .rel(.{ .sym_index = sym.nlist_idx }));
173849 } else if (self.bin_file.cast(.plan9)) |p9| {
173850 const atom_index = try p9.seeNav(pt, func.owner_nav);
173851 const atom = p9.getAtom(atom_index);
173852 try self.asmMemory(.{ ._, .call }, .{
173853 .base = .{ .reg = .ds },
173854 .mod = .{ .rm = .{
173855 .size = .qword,
173856 .disp = @intCast(atom.getOffsetTableAddress(p9)),
173857 } },
173858 });
173859 } else unreachable;
173860 },
173861 .@"extern" => |@"extern"| if (self.bin_file.cast(.elf)) |elf_file| {
173862 const target_sym_index = try elf_file.getGlobalSymbol(
173863 @"extern".name.toSlice(ip),
173864 @"extern".lib_name.toSlice(ip),
173865 );
173866 try self.asmImmediate(.{ ._, .call }, .rel(.{ .sym_index = target_sym_index }));
173867 } else if (self.bin_file.cast(.macho)) |macho_file| {
173868 const target_sym_index = try macho_file.getGlobalSymbol(
173869 @"extern".name.toSlice(ip),
173870 @"extern".lib_name.toSlice(ip),
173871 );
173872 try self.asmImmediate(.{ ._, .call }, .rel(.{ .sym_index = target_sym_index }));
173873 } else try self.genExternSymbolRef(
173874 .call,
173875 @"extern".lib_name.toSlice(ip),
173876 @"extern".name.toSlice(ip),
173877 ),
173878 else => return self.fail("TODO implement calling bitcasted functions", .{}),
173879 }173698 }
173880 } else {173699 } else {
173881 assert(self.typeOf(callee).zigTypeTag(zcu) == .pointer);173700 assert(self.typeOf(callee).zigTypeTag(zcu) == .pointer);
...@@ -173883,13 +173702,7 @@ fn genCall(self: *CodeGen, info: union(enum) {...@@ -173883,13 +173702,7 @@ fn genCall(self: *CodeGen, info: union(enum) {
173883 try self.genSetReg(scratch_reg, .usize, .{ .air_ref = callee }, .{});173702 try self.genSetReg(scratch_reg, .usize, .{ .air_ref = callee }, .{});
173884 try self.asmRegister(.{ ._, .call }, scratch_reg);173703 try self.asmRegister(.{ ._, .call }, scratch_reg);
173885 },173704 },
173886 .lib => |lib| if (self.bin_file.cast(.elf)) |elf_file| {173705 .extern_func => |extern_func| try self.asmImmediate(.{ ._, .call }, .{ .extern_func = try self.addString(extern_func.sym) }),
173887 const target_sym_index = try elf_file.getGlobalSymbol(lib.callee, lib.lib);
173888 try self.asmImmediate(.{ ._, .call }, .rel(.{ .sym_index = target_sym_index }));
173889 } else if (self.bin_file.cast(.macho)) |macho_file| {
173890 const target_sym_index = try macho_file.getGlobalSymbol(lib.callee, lib.lib);
173891 try self.asmImmediate(.{ ._, .call }, .rel(.{ .sym_index = target_sym_index }));
173892 } else try self.genExternSymbolRef(.call, lib.lib, lib.callee),
173893 }173706 }
173894 return call_info.return_value.short;173707 return call_info.return_value.short;
173895}173708}
...@@ -174023,11 +173836,11 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v...@@ -174023,11 +173836,11 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v
174023 80, 128 => false,173836 80, 128 => false,
174024 else => unreachable,173837 else => unreachable,
174025 }) {173838 }) {
174026 var callee_buf: ["__???f2".len]u8 = undefined;173839 var sym_buf: ["__???f2".len]u8 = undefined;
174027 const ret = try self.genCall(.{ .lib = .{173840 const ret = try self.genCall(.{ .extern_func = .{
174028 .return_type = .i32_type,173841 .return_type = .i32_type,
174029 .param_types = &.{ ty.toIntern(), ty.toIntern() },173842 .param_types = &.{ ty.toIntern(), ty.toIntern() },
174030 .callee = std.fmt.bufPrint(&callee_buf, "__{s}{c}f2", .{173843 .sym = std.fmt.bufPrint(&sym_buf, "__{s}{c}f2", .{
174031 switch (op) {173844 switch (op) {
174032 .eq => "eq",173845 .eq => "eq",
174033 .neq => "ne",173846 .neq => "ne",
...@@ -174170,17 +173983,27 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v...@@ -174170,17 +173983,27 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v
174170 .register_overflow,173983 .register_overflow,
174171 .register_mask,173984 .register_mask,
174172 .indirect,173985 .indirect,
174173 .lea_direct,
174174 .lea_got,
174175 .lea_frame,173986 .lea_frame,
174176 .lea_symbol,173987 .lea_nav,
174177 .lea_pcrel,173988 .lea_uav,
173989 .lea_lazy_sym,
173990 .lea_extern_func,
174178 .elementwise_args,173991 .elementwise_args,
174179 .reserved_frame,173992 .reserved_frame,
174180 .air_ref,173993 .air_ref,
174181 => unreachable,173994 => unreachable,
174182 .register, .register_pair, .register_triple, .register_quadruple, .load_frame => null,173995 .register,
174183 .memory, .load_symbol, .load_pcrel, .load_got, .load_direct => dst: {173996 .register_pair,
173997 .register_triple,
173998 .register_quadruple,
173999 .load_frame,
174000 => null,
174001 .memory,
174002 .load_nav,
174003 .load_uav,
174004 .load_lazy_sym,
174005 .load_extern_func,
174006 => dst: {
174184 switch (resolved_dst_mcv) {174007 switch (resolved_dst_mcv) {
174185 .memory => |addr| if (std.math.cast(174008 .memory => |addr| if (std.math.cast(
174186 i32,174009 i32,
...@@ -174189,7 +174012,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v...@@ -174189,7 +174012,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v
174189 i32,174012 i32,
174190 @as(i64, @bitCast(addr)) + abi_size - 8,174013 @as(i64, @bitCast(addr)) + abi_size - 8,
174191 ) != null) break :dst null,174014 ) != null) break :dst null,
174192 .load_symbol, .load_pcrel, .load_got, .load_direct => {},174015 .load_nav, .load_uav, .load_lazy_sym, .load_extern_func => {},
174193 else => unreachable,174016 else => unreachable,
174194 }174017 }
174195174018
...@@ -174226,17 +174049,26 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v...@@ -174226,17 +174049,26 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v
174226 .register_overflow,174049 .register_overflow,
174227 .register_mask,174050 .register_mask,
174228 .indirect,174051 .indirect,
174229 .lea_symbol,
174230 .lea_pcrel,
174231 .lea_direct,
174232 .lea_got,
174233 .lea_frame,174052 .lea_frame,
174053 .lea_nav,
174054 .lea_uav,
174055 .lea_lazy_sym,
174056 .lea_extern_func,
174234 .elementwise_args,174057 .elementwise_args,
174235 .reserved_frame,174058 .reserved_frame,
174236 .air_ref,174059 .air_ref,
174237 => unreachable,174060 => unreachable,
174238 .register_pair, .register_triple, .register_quadruple, .load_frame => null,174061 .register_pair,
174239 .memory, .load_symbol, .load_pcrel, .load_got, .load_direct => src: {174062 .register_triple,
174063 .register_quadruple,
174064 .load_frame,
174065 => null,
174066 .memory,
174067 .load_nav,
174068 .load_uav,
174069 .load_lazy_sym,
174070 .load_extern_func,
174071 => src: {
174240 switch (resolved_src_mcv) {174072 switch (resolved_src_mcv) {
174241 .memory => |addr| if (std.math.cast(174073 .memory => |addr| if (std.math.cast(
174242 i32,174074 i32,
...@@ -174245,7 +174077,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v...@@ -174245,7 +174077,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v
174245 i32,174077 i32,
174246 @as(i64, @bitCast(addr)) + abi_size - 8,174078 @as(i64, @bitCast(addr)) + abi_size - 8,
174247 ) != null) break :src null,174079 ) != null) break :src null,
174248 .load_symbol, .load_pcrel, .load_got, .load_direct => {},174080 .load_nav, .load_uav, .load_lazy_sym, .load_extern_func => {},
174249 else => unreachable,174081 else => unreachable,
174250 }174082 }
174251174083
...@@ -174526,10 +174358,31 @@ fn genTry(...@@ -174526,10 +174358,31 @@ fn genTry(
174526 return result;174358 return result;
174527}174359}
174528174360
174529fn airDbgVar(self: *CodeGen, inst: Air.Inst.Index) !void {174361fn airDbgVar(cg: *CodeGen, inst: Air.Inst.Index) !void {
174530 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;174362 if (cg.mod.strip) return;
174531 try self.genLocalDebugInfo(inst, try self.resolveInst(pl_op.operand));174363 const air_tag = cg.air.instructions.items(.tag)[@intFromEnum(inst)];
174532 return self.finishAir(inst, .unreach, .{ pl_op.operand, .none, .none });174364 const pl_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
174365 const air_name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
174366 const op_ty = cg.typeOf(pl_op.operand);
174367 const local_ty = switch (air_tag) {
174368 else => unreachable,
174369 .dbg_var_ptr => op_ty.childType(cg.pt.zcu),
174370 .dbg_var_val, .dbg_arg_inline => op_ty,
174371 };
174372
174373 try cg.mir_locals.append(cg.gpa, .{
174374 .name = switch (air_name) {
174375 .none => switch (air_tag) {
174376 else => unreachable,
174377 .dbg_arg_inline => .none,
174378 },
174379 else => try cg.addString(air_name.toSlice(cg.air)),
174380 },
174381 .type = local_ty.toIntern(),
174382 });
174383
174384 try cg.genLocalDebugInfo(air_tag, local_ty, try cg.resolveInst(pl_op.operand));
174385 return cg.finishAir(inst, .unreach, .{ pl_op.operand, .none, .none });
174533}174386}
174534174387
174535fn genCondBrMir(self: *CodeGen, ty: Type, mcv: MCValue) !Mir.Inst.Index {174388fn genCondBrMir(self: *CodeGen, ty: Type, mcv: MCValue) !Mir.Inst.Index {
...@@ -174633,10 +174486,10 @@ fn isNull(self: *CodeGen, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue)...@@ -174633,10 +174486,10 @@ fn isNull(self: *CodeGen, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue)
174633 .register_offset,174486 .register_offset,
174634 .register_overflow,174487 .register_overflow,
174635 .register_mask,174488 .register_mask,
174636 .lea_direct,174489 .lea_nav,
174637 .lea_got,174490 .lea_uav,
174638 .lea_symbol,174491 .lea_lazy_sym,
174639 .lea_pcrel,174492 .lea_extern_func,
174640 .elementwise_args,174493 .elementwise_args,
174641 .reserved_frame,174494 .reserved_frame,
174642 .air_ref,174495 .air_ref,
...@@ -174684,10 +174537,10 @@ fn isNull(self: *CodeGen, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue)...@@ -174684,10 +174537,10 @@ fn isNull(self: *CodeGen, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue)
174684 },174537 },
174685174538
174686 .memory,174539 .memory,
174687 .load_symbol,174540 .load_nav,
174688 .load_pcrel,174541 .load_uav,
174689 .load_got,174542 .load_lazy_sym,
174690 .load_direct,174543 .load_extern_func,
174691 => {174544 => {
174692 const addr_reg = (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();174545 const addr_reg = (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();
174693 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);174546 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
...@@ -175721,7 +175574,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -175721,7 +175574,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
175721 .memory => |addr| if (std.math.cast(i32, @as(i64, @bitCast(addr)))) |_|175574 .memory => |addr| if (std.math.cast(i32, @as(i64, @bitCast(addr)))) |_|
175722 break :arg input_mcv,175575 break :arg input_mcv,
175723 .indirect, .load_frame => break :arg input_mcv,175576 .indirect, .load_frame => break :arg input_mcv,
175724 .load_symbol, .load_direct, .load_got => {},175577 .load_nav, .load_uav, .load_lazy_sym, .load_extern_func => {},
175725 else => {175578 else => {
175726 const temp_mcv = try self.allocTempRegOrMem(ty, false);175579 const temp_mcv = try self.allocTempRegOrMem(ty, false);
175727 try self.genCopy(ty, temp_mcv, input_mcv, .{});175580 try self.genCopy(ty, temp_mcv, input_mcv, .{});
...@@ -176000,12 +175853,20 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -176000,12 +175853,20 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
176000 } }175853 } }
176001 else175854 else
176002 return self.fail("invalid modifier: '{s}'", .{modifier}),175855 return self.fail("invalid modifier: '{s}'", .{modifier}),
176003 .lea_got => |sym_index| if (std.mem.eql(u8, modifier, "P"))175856 .lea_nav => |nav| if (std.mem.eql(u8, modifier, "P"))
176004 .{ .reg = try self.copyToTmpRegister(.usize, .{ .lea_got = sym_index }) }175857 .{ .reg = try self.copyToTmpRegister(.usize, .{ .lea_nav = nav }) }
175858 else
175859 return self.fail("invalid modifier: '{s}'", .{modifier}),
175860 .lea_uav => |uav| if (std.mem.eql(u8, modifier, "P"))
175861 .{ .reg = try self.copyToTmpRegister(.usize, .{ .lea_uav = uav }) }
175862 else
175863 return self.fail("invalid modifier: '{s}'", .{modifier}),
175864 .lea_lazy_sym => |lazy_sym| if (std.mem.eql(u8, modifier, "P"))
175865 .{ .reg = try self.copyToTmpRegister(.usize, .{ .lea_lazy_sym = lazy_sym }) }
176005 else175866 else
176006 return self.fail("invalid modifier: '{s}'", .{modifier}),175867 return self.fail("invalid modifier: '{s}'", .{modifier}),
176007 .lea_symbol => |sym_off| if (std.mem.eql(u8, modifier, "P"))175868 .lea_extern_func => |extern_func| if (std.mem.eql(u8, modifier, "P"))
176008 .{ .reg = try self.copyToTmpRegister(.usize, .{ .lea_symbol = sym_off }) }175869 .{ .reg = try self.copyToTmpRegister(.usize, .{ .lea_extern_func = extern_func }) }
176009 else175870 else
176010 return self.fail("invalid modifier: '{s}'", .{modifier}),175871 return self.fail("invalid modifier: '{s}'", .{modifier}),
176011 else => return self.fail("invalid constraint: '{s}'", .{op_str}),175872 else => return self.fail("invalid constraint: '{s}'", .{op_str}),
...@@ -176689,11 +176550,11 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C...@@ -176689,11 +176550,11 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
176689 .eflags,176550 .eflags,
176690 .register_overflow,176551 .register_overflow,
176691 .register_mask,176552 .register_mask,
176692 .lea_direct,
176693 .lea_got,
176694 .lea_frame,176553 .lea_frame,
176695 .lea_symbol,176554 .lea_nav,
176696 .lea_pcrel,176555 .lea_uav,
176556 .lea_lazy_sym,
176557 .lea_extern_func,
176697 .elementwise_args,176558 .elementwise_args,
176698 .reserved_frame,176559 .reserved_frame,
176699 .air_ref,176560 .air_ref,
...@@ -176788,7 +176649,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C...@@ -176788,7 +176649,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
176788 }176649 }
176789 return;176650 return;
176790 },176651 },
176791 .load_symbol, .load_pcrel, .load_direct, .load_got => {176652 .load_nav, .load_uav, .load_lazy_sym, .load_extern_func => {
176792 const src_addr_reg =176653 const src_addr_reg =
176793 (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();176654 (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();
176794 const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg);176655 const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg);
...@@ -176821,7 +176682,11 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C...@@ -176821,7 +176682,11 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
176821 .undef => if (opts.safety and part_i > 0) .{ .register = dst_regs[0] } else .undef,176682 .undef => if (opts.safety and part_i > 0) .{ .register = dst_regs[0] } else .undef,
176822 dst_tag => |src_regs| .{ .register = src_regs[part_i] },176683 dst_tag => |src_regs| .{ .register = src_regs[part_i] },
176823 .memory, .indirect, .load_frame => src_mcv.address().offset(part_disp).deref(),176684 .memory, .indirect, .load_frame => src_mcv.address().offset(part_disp).deref(),
176824 .load_symbol, .load_pcrel, .load_direct, .load_got => .{ .indirect = .{176685 .load_nav,
176686 .load_uav,
176687 .load_lazy_sym,
176688 .load_extern_func,
176689 => .{ .indirect = .{
176825 .reg = src_info.?.addr_reg,176690 .reg = src_info.?.addr_reg,
176826 .off = part_disp,176691 .off = part_disp,
176827 } },176692 } },
...@@ -176842,11 +176707,11 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C...@@ -176842,11 +176707,11 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
176842 src_mcv,176707 src_mcv,
176843 opts,176708 opts,
176844 ),176709 ),
176845 .memory, .load_symbol, .load_pcrel, .load_direct, .load_got => {176710 .memory => {
176846 switch (dst_mcv) {176711 switch (dst_mcv) {
176847 .memory => |addr| if (std.math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|176712 .memory => |addr| if (std.math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|
176848 return self.genSetMem(.{ .reg = .ds }, small_addr, ty, src_mcv, opts),176713 return self.genSetMem(.{ .reg = .ds }, small_addr, ty, src_mcv, opts),
176849 .load_symbol, .load_pcrel, .load_direct, .load_got => {},176714 .load_nav, .load_uav, .load_lazy_sym, .load_extern_func => {},
176850 else => unreachable,176715 else => unreachable,
176851 }176716 }
176852176717
...@@ -176863,6 +176728,10 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C...@@ -176863,6 +176728,10 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
176863 src_mcv,176728 src_mcv,
176864 opts,176729 opts,
176865 ),176730 ),
176731 .load_nav => |nav| try self.genSetMem(.{ .nav = nav }, 0, ty, src_mcv, opts),
176732 .load_uav => |uav| try self.genSetMem(.{ .uav = uav }, 0, ty, src_mcv, opts),
176733 .load_lazy_sym => |lazy_sym| try self.genSetMem(.{ .lazy_sym = lazy_sym }, 0, ty, src_mcv, opts),
176734 .load_extern_func => |extern_func| try self.genSetMem(.{ .extern_func = extern_func }, 0, ty, src_mcv, opts),
176866 }176735 }
176867}176736}
176868176737
...@@ -176907,14 +176776,14 @@ fn genSetReg(...@@ -176907,14 +176776,14 @@ fn genSetReg(
176907 .len = self.vectorSize(.float),176776 .len = self.vectorSize(.float),
176908 .child = .u8_type,176777 .child = .u8_type,
176909 });176778 });
176910 try self.genSetReg(dst_reg, full_ty, try self.genTypedValue(176779 try self.genSetReg(dst_reg, full_ty, try self.lowerValue(
176911 .fromInterned(try pt.intern(.{ .aggregate = .{176780 .fromInterned(try pt.intern(.{ .aggregate = .{
176912 .ty = full_ty.toIntern(),176781 .ty = full_ty.toIntern(),
176913 .storage = .{ .repeated_elem = (try pt.intValue(.u8, 0xaa)).toIntern() },176782 .storage = .{ .repeated_elem = (try pt.intValue(.u8, 0xaa)).toIntern() },
176914 } })),176783 } })),
176915 ), opts);176784 ), opts);
176916 },176785 },
176917 .x87 => try self.genSetReg(dst_reg, .f80, try self.genTypedValue(176786 .x87 => try self.genSetReg(dst_reg, .f80, try self.lowerValue(
176918 try pt.floatValue(.f80, @as(f80, @bitCast(@as(u80, 0xaaaaaaaaaaaaaaaaaaaa)))),176787 try pt.floatValue(.f80, @as(f80, @bitCast(@as(u80, 0xaaaaaaaaaaaaaaaaaaaa)))),
176919 ), opts),176788 ), opts),
176920 .ip, .cr, .dr => unreachable,176789 .ip, .cr, .dr => unreachable,
...@@ -176944,12 +176813,24 @@ fn genSetReg(...@@ -176944,12 +176813,24 @@ fn genSetReg(
176944 }176813 }
176945 },176814 },
176946 .register => |src_reg| if (dst_reg.id() != src_reg.id()) switch (dst_reg.class()) {176815 .register => |src_reg| if (dst_reg.id() != src_reg.id()) switch (dst_reg.class()) {
176947 .general_purpose, .gphi => switch (src_reg.class()) {176816 .general_purpose => switch (src_reg.class()) {
176948 .general_purpose, .gphi => try self.asmRegisterRegister(176817 .general_purpose => try self.asmRegisterRegister(
176949 .{ ._, .mov },176818 .{ ._, .mov },
176950 dst_alias,176819 dst_alias,
176951 registerAlias(src_reg, abi_size),176820 registerAlias(src_reg, abi_size),
176952 ),176821 ),
176822 .gphi => if (dst_reg.isClass(.gphi)) try self.asmRegisterRegister(
176823 .{ ._, .mov },
176824 dst_alias,
176825 registerAlias(src_reg, abi_size),
176826 ) else {
176827 const src_lock = self.register_manager.lockReg(src_reg);
176828 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
176829 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gphi);
176830
176831 try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg.to8(), src_reg);
176832 try self.asmRegisterRegister(.{ ._, .mov }, dst_alias, tmp_reg.to8());
176833 },
176953 .segment => try self.asmRegisterRegister(176834 .segment => try self.asmRegisterRegister(
176954 .{ ._, .mov },176835 .{ ._, .mov },
176955 dst_alias,176836 dst_alias,
...@@ -176985,6 +176866,26 @@ fn genSetReg(...@@ -176985,6 +176866,26 @@ fn genSetReg(
176985 });176866 });
176986 },176867 },
176987 },176868 },
176869 .gphi => switch (src_reg.class()) {
176870 .general_purpose => if (src_reg.isClass(.gphi)) try self.asmRegisterRegister(
176871 .{ ._, .mov },
176872 dst_alias,
176873 registerAlias(src_reg, abi_size),
176874 ) else {
176875 const dst_lock = self.register_manager.lockReg(dst_reg);
176876 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
176877 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gphi);
176878
176879 try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg.to8(), src_reg.to8());
176880 try self.asmRegisterRegister(.{ ._, .mov }, dst_reg, tmp_reg.to8());
176881 },
176882 .gphi => try self.asmRegisterRegister(
176883 .{ ._, .mov },
176884 dst_alias,
176885 registerAlias(src_reg, abi_size),
176886 ),
176887 .segment, .x87, .mmx, .ip, .cr, .dr, .sse => unreachable,
176888 },
176988 .segment => try self.asmRegisterRegister(176889 .segment => try self.asmRegisterRegister(
176989 .{ ._, .mov },176890 .{ ._, .mov },
176990 dst_reg,176891 dst_reg,
...@@ -177303,7 +177204,7 @@ fn genSetReg(...@@ -177303,7 +177204,7 @@ fn genSetReg(
177303 if (src_reg_mask.info.inverted) try self.asmRegister(.{ ._, .not }, registerAlias(bits_reg, abi_size));177204 if (src_reg_mask.info.inverted) try self.asmRegister(.{ ._, .not }, registerAlias(bits_reg, abi_size));
177304 try self.genSetReg(dst_reg, ty, .{ .register = bits_reg }, .{});177205 try self.genSetReg(dst_reg, ty, .{ .register = bits_reg }, .{});
177305 },177206 },
177306 .memory, .load_symbol, .load_pcrel, .load_direct, .load_got => {177207 .memory, .load_nav, .load_uav, .load_lazy_sym, .load_extern_func => {
177307 switch (src_mcv) {177208 switch (src_mcv) {
177308 .memory => |addr| if (std.math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|177209 .memory => |addr| if (std.math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|
177309 return (try self.moveStrategy(177210 return (try self.moveStrategy(
...@@ -177317,52 +177218,50 @@ fn genSetReg(...@@ -177317,52 +177218,50 @@ fn genSetReg(
177317 .disp = small_addr,177218 .disp = small_addr,
177318 } },177219 } },
177319 }),177220 }),
177320 .load_symbol => |sym_off| switch (dst_reg.class()) {177221 .load_nav => |nav| switch (dst_reg.class()) {
177321 .general_purpose, .gphi => {177222 .general_purpose, .gphi => {
177322 assert(sym_off.off == 0);
177323 try self.asmRegisterMemory(.{ ._, .mov }, dst_alias, .{177223 try self.asmRegisterMemory(.{ ._, .mov }, dst_alias, .{
177324 .base = .{ .reloc = sym_off.sym_index },177224 .base = .{ .nav = nav },
177325 .mod = .{ .rm = .{177225 .mod = .{ .rm = .{ .size = self.memSize(ty) } },
177326 .size = self.memSize(ty),
177327 .disp = sym_off.off,
177328 } },
177329 });177226 });
177330 return;177227 return;
177331 },177228 },
177332 .segment, .mmx, .ip, .cr, .dr => unreachable,177229 .segment, .mmx, .ip, .cr, .dr => unreachable,
177333 .x87, .sse => {},177230 .x87, .sse => {},
177334 },177231 },
177335 .load_pcrel => |sym_off| switch (dst_reg.class()) {177232 .load_uav => |uav| switch (dst_reg.class()) {
177336 .general_purpose, .gphi => {177233 .general_purpose, .gphi => {
177337 assert(sym_off.off == 0);
177338 try self.asmRegisterMemory(.{ ._, .mov }, dst_alias, .{177234 try self.asmRegisterMemory(.{ ._, .mov }, dst_alias, .{
177339 .base = .{ .pcrel = sym_off.sym_index },177235 .base = .{ .uav = uav },
177340 .mod = .{ .rm = .{177236 .mod = .{ .rm = .{ .size = self.memSize(ty) } },
177341 .size = self.memSize(ty),
177342 .disp = sym_off.off,
177343 } },
177344 });177237 });
177345 return;177238 return;
177346 },177239 },
177347 .segment, .mmx, .ip, .cr, .dr => unreachable,177240 .segment, .mmx, .ip, .cr, .dr => unreachable,
177348 .x87, .sse => {},177241 .x87, .sse => {},
177349 },177242 },
177350 .load_direct => |sym_index| switch (dst_reg.class()) {177243 .load_lazy_sym => |lazy_sym| switch (dst_reg.class()) {
177351 .general_purpose, .gphi => {177244 .general_purpose, .gphi => {
177352 _ = try self.addInst(.{177245 try self.asmRegisterMemory(.{ ._, .mov }, dst_alias, .{
177353 .tag = .mov,177246 .base = .{ .lazy_sym = lazy_sym },
177354 .ops = .direct_reloc,177247 .mod = .{ .rm = .{ .size = self.memSize(ty) } },
177355 .data = .{ .rx = .{177248 });
177356 .r1 = dst_alias,177249 return;
177357 .payload = try self.addExtra(bits.SymbolOffset{ .sym_index = sym_index }),177250 },
177358 } },177251 .segment, .mmx, .ip, .cr, .dr => unreachable,
177252 .x87, .sse => {},
177253 },
177254 .load_extern_func => |extern_func| switch (dst_reg.class()) {
177255 .general_purpose, .gphi => {
177256 try self.asmRegisterMemory(.{ ._, .mov }, dst_alias, .{
177257 .base = .{ .extern_func = extern_func },
177258 .mod = .{ .rm = .{ .size = self.memSize(ty) } },
177359 });177259 });
177360 return;177260 return;
177361 },177261 },
177362 .segment, .mmx, .ip, .cr, .dr => unreachable,177262 .segment, .mmx, .ip, .cr, .dr => unreachable,
177363 .x87, .sse => {},177263 .x87, .sse => {},
177364 },177264 },
177365 .load_got => {},
177366 else => unreachable,177265 else => unreachable,
177367 }177266 }
177368177267
...@@ -177375,65 +177274,17 @@ fn genSetReg(...@@ -177375,65 +177274,17 @@ fn genSetReg(
177375 .mod = .{ .rm = .{ .size = self.memSize(ty) } },177274 .mod = .{ .rm = .{ .size = self.memSize(ty) } },
177376 });177275 });
177377 },177276 },
177378 .lea_symbol => |sym_off| switch (self.bin_file.tag) {177277 .lea_nav => |nav| try self.asmRegisterMemory(.{ ._, .lea }, dst_reg.to64(), .{
177379 .elf, .macho => {177278 .base = .{ .nav = nav },
177380 try self.asmRegisterMemory(177279 }),
177381 .{ ._, .lea },177280 .lea_uav => |uav| try self.asmRegisterMemory(.{ ._, .lea }, dst_reg.to64(), .{
177382 dst_reg.to64(),177281 .base = .{ .uav = uav },
177383 .{177282 }),
177384 .base = .{ .reloc = sym_off.sym_index },177283 .lea_lazy_sym => |lazy_sym| try self.asmRegisterMemory(.{ ._, .lea }, dst_reg.to64(), .{
177385 },177284 .base = .{ .lazy_sym = lazy_sym },
177386 );177285 }),
177387 if (sym_off.off != 0) try self.asmRegisterMemory(177286 .lea_extern_func => |lazy_sym| try self.asmRegisterMemory(.{ ._, .lea }, dst_reg.to64(), .{
177388 .{ ._, .lea },177287 .base = .{ .extern_func = lazy_sym },
177389 dst_reg.to64(),
177390 .{
177391 .base = .{ .reg = dst_reg.to64() },
177392 .mod = .{ .rm = .{ .disp = sym_off.off } },
177393 },
177394 );
177395 },
177396 else => return self.fail("TODO emit symbol sequence on {s}", .{
177397 @tagName(self.bin_file.tag),
177398 }),
177399 },
177400 .lea_pcrel => |sym_off| switch (self.bin_file.tag) {
177401 .elf, .macho => {
177402 try self.asmRegisterMemory(
177403 .{ ._, .lea },
177404 dst_reg.to64(),
177405 .{
177406 .base = .{ .pcrel = sym_off.sym_index },
177407 },
177408 );
177409 if (sym_off.off != 0) try self.asmRegisterMemory(
177410 .{ ._, .lea },
177411 dst_reg.to64(),
177412 .{
177413 .base = .{ .reg = dst_reg.to64() },
177414 .mod = .{ .rm = .{ .disp = sym_off.off } },
177415 },
177416 );
177417 },
177418 else => return self.fail("TODO emit symbol sequence on {s}", .{
177419 @tagName(self.bin_file.tag),
177420 }),
177421 },
177422 .lea_direct, .lea_got => |sym_index| _ = try self.addInst(.{
177423 .tag = switch (src_mcv) {
177424 .lea_direct => .lea,
177425 .lea_got => .mov,
177426 else => unreachable,
177427 },
177428 .ops = switch (src_mcv) {
177429 .lea_direct => .direct_reloc,
177430 .lea_got => .got_reloc,
177431 else => unreachable,
177432 },
177433 .data = .{ .rx = .{
177434 .r1 = dst_reg.to64(),
177435 .payload = try self.addExtra(bits.SymbolOffset{ .sym_index = sym_index }),
177436 } },
177437 }),177288 }),
177438 .air_ref => |src_ref| try self.genSetReg(dst_reg, ty, try self.resolveInst(src_ref), opts),177289 .air_ref => |src_ref| try self.genSetReg(dst_reg, ty, try self.resolveInst(src_ref), opts),
177439 }177290 }
...@@ -177454,9 +177305,10 @@ fn genSetMem(...@@ -177454,9 +177305,10 @@ fn genSetMem(
177454 .none => .{ .immediate = @bitCast(@as(i64, disp)) },177305 .none => .{ .immediate = @bitCast(@as(i64, disp)) },
177455 .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } },177306 .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } },
177456 .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } },177307 .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } },
177457 .table, .rip_inst => unreachable,177308 .table, .rip_inst, .lazy_sym => unreachable,
177458 .reloc => |sym_index| .{ .lea_symbol = .{ .sym_index = sym_index, .off = disp } },177309 .nav => |nav| .{ .lea_nav = nav },
177459 .pcrel => |sym_index| .{ .lea_pcrel = .{ .sym_index = sym_index, .off = disp } },177310 .uav => |uav| .{ .lea_uav = uav },
177311 .extern_func => |extern_func| .{ .lea_extern_func = extern_func },
177460 };177312 };
177461 switch (src_mcv) {177313 switch (src_mcv) {
177462 .none,177314 .none,
...@@ -177519,6 +177371,7 @@ fn genSetMem(...@@ -177519,6 +177371,7 @@ fn genSetMem(
177519 .rm = .{ .size = .byte, .disp = disp },177371 .rm = .{ .size = .byte, .disp = disp },
177520 } }),177372 } }),
177521 .register => |src_reg| {177373 .register => |src_reg| {
177374 const ip = &zcu.intern_pool;
177522 const mem_size = switch (base) {177375 const mem_size = switch (base) {
177523 .frame => |base_fi| mem_size: {177376 .frame => |base_fi| mem_size: {
177524 assert(disp >= 0);177377 assert(disp >= 0);
...@@ -177572,8 +177425,9 @@ fn genSetMem(...@@ -177572,8 +177425,9 @@ fn genSetMem(
177572 .index = frame_index,177425 .index = frame_index,
177573 .off = disp,177426 .off = disp,
177574 }).compare(.gte, src_align),177427 }).compare(.gte, src_align),
177575 .table, .rip_inst => unreachable,177428 .table, .rip_inst, .lazy_sym, .extern_func => unreachable,
177576 .reloc, .pcrel => false,177429 .nav => |nav| ip.getNav(nav).getAlignment().compare(.gte, src_align),
177430 .uav => |uav| Type.fromInterned(uav.orig_ty).ptrAlignment(zcu).compare(.gte, src_align),
177577 })).write(177431 })).write(
177578 self,177432 self,
177579 .{ .base = base, .mod = .{ .rm = .{177433 .{ .base = base, .mod = .{ .rm = .{
...@@ -177656,16 +177510,16 @@ fn genSetMem(...@@ -177656,16 +177510,16 @@ fn genSetMem(
177656 },177510 },
177657 .memory,177511 .memory,
177658 .indirect,177512 .indirect,
177659 .load_direct,
177660 .lea_direct,
177661 .load_got,
177662 .lea_got,
177663 .load_frame,177513 .load_frame,
177664 .lea_frame,177514 .lea_frame,
177665 .load_symbol,177515 .load_nav,
177666 .lea_symbol,177516 .lea_nav,
177667 .load_pcrel,177517 .load_uav,
177668 .lea_pcrel,177518 .lea_uav,
177519 .load_lazy_sym,
177520 .lea_lazy_sym,
177521 .load_extern_func,
177522 .lea_extern_func,
177669 => switch (abi_size) {177523 => switch (abi_size) {
177670 0 => {},177524 0 => {},
177671 1, 2, 4, 8 => {177525 1, 2, 4, 8 => {
...@@ -177759,119 +177613,19 @@ fn genInlineMemset(...@@ -177759,119 +177613,19 @@ fn genInlineMemset(
177759 try self.asmOpOnly(.{ .@"rep _sb", .sto });177613 try self.asmOpOnly(.{ .@"rep _sb", .sto });
177760}177614}
177761177615
177762fn genExternSymbolRef(
177763 self: *CodeGen,
177764 comptime tag: Mir.Inst.Tag,
177765 lib: ?[]const u8,
177766 callee: []const u8,
177767) InnerError!void {
177768 if (self.bin_file.cast(.coff)) |coff_file| {
177769 const global_index = try coff_file.getGlobalSymbol(callee, lib);
177770 const scratch_reg = abi.getCAbiLinkerScratchReg(self.target.cCallingConvention().?);
177771 _ = try self.addInst(.{
177772 .tag = .mov,
177773 .ops = .import_reloc,
177774 .data = .{ .rx = .{
177775 .r1 = scratch_reg,
177776 .payload = try self.addExtra(bits.SymbolOffset{
177777 .sym_index = link.File.Coff.global_symbol_bit | global_index,
177778 }),
177779 } },
177780 });
177781 switch (tag) {
177782 .mov => {},
177783 .call => try self.asmRegister(.{ ._, .call }, scratch_reg),
177784 else => unreachable,
177785 }
177786 } else return self.fail("TODO implement calling extern functions", .{});
177787}
177788
177789fn genLazySymbolRef(177616fn genLazySymbolRef(
177790 self: *CodeGen,177617 self: *CodeGen,
177791 comptime tag: Mir.Inst.Tag,177618 comptime tag: Mir.Inst.Tag,
177792 reg: Register,177619 reg: Register,
177793 lazy_sym: link.File.LazySymbol,177620 lazy_sym: link.File.LazySymbol,
177794) InnerError!void {177621) InnerError!void {
177795 const pt = self.pt;177622 if (self.mod.pic) {
177796 if (self.bin_file.cast(.elf)) |elf_file| {
177797 const zo = elf_file.zigObjectPtr().?;
177798 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
177799 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
177800 if (self.mod.pic) {
177801 switch (tag) {
177802 .lea, .call => try self.genSetReg(reg, .usize, .{
177803 .lea_symbol = .{ .sym_index = sym_index },
177804 }, .{}),
177805 .mov => try self.genSetReg(reg, .usize, .{
177806 .load_symbol = .{ .sym_index = sym_index },
177807 }, .{}),
177808 else => unreachable,
177809 }
177810 switch (tag) {
177811 .lea, .mov => {},
177812 .call => try self.asmRegister(.{ ._, .call }, reg),
177813 else => unreachable,
177814 }
177815 } else switch (tag) {
177816 .lea, .mov => try self.asmRegisterMemory(.{ ._, tag }, reg.to64(), .{
177817 .base = .{ .reloc = sym_index },
177818 .mod = .{ .rm = .{ .size = .qword } },
177819 }),
177820 .call => try self.asmImmediate(.{ ._, .call }, .rel(.{ .sym_index = sym_index })),
177821 else => unreachable,
177822 }
177823 } else if (self.bin_file.cast(.plan9)) |p9_file| {
177824 const atom_index = p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
177825 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
177826 var atom = p9_file.getAtom(atom_index);
177827 _ = atom.getOrCreateOffsetTableEntry(p9_file);
177828 const got_addr = atom.getOffsetTableAddress(p9_file);
177829 const got_mem: Memory = .{
177830 .base = .{ .reg = .ds },
177831 .mod = .{ .rm = .{
177832 .size = .qword,
177833 .disp = @intCast(got_addr),
177834 } },
177835 };
177836 switch (tag) {
177837 .lea, .mov => try self.asmRegisterMemory(.{ ._, .mov }, reg.to64(), got_mem),
177838 .call => try self.asmMemory(.{ ._, .call }, got_mem),
177839 else => unreachable,
177840 }
177841 switch (tag) {
177842 .lea, .call => {},
177843 .mov => try self.asmRegisterMemory(
177844 .{ ._, tag },
177845 reg.to64(),
177846 .initSib(.qword, .{ .base = .{ .reg = reg.to64() } }),
177847 ),
177848 else => unreachable,
177849 }
177850 } else if (self.bin_file.cast(.coff)) |coff_file| {
177851 const atom_index = coff_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
177852 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
177853 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
177854 switch (tag) {
177855 .lea, .call => try self.genSetReg(reg, .usize, .{ .lea_got = sym_index }, .{}),
177856 .mov => try self.genSetReg(reg, .usize, .{ .load_got = sym_index }, .{}),
177857 else => unreachable,
177858 }
177859 switch (tag) {
177860 .lea, .mov => {},
177861 .call => try self.asmRegister(.{ ._, .call }, reg),
177862 else => unreachable,
177863 }
177864 } else if (self.bin_file.cast(.macho)) |macho_file| {
177865 const zo = macho_file.getZigObject().?;
177866 const sym_index = zo.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|
177867 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
177868 const sym = zo.symbols.items[sym_index];
177869 switch (tag) {177623 switch (tag) {
177870 .lea, .call => try self.genSetReg(reg, .usize, .{177624 .lea, .call => try self.genSetReg(reg, .usize, .{
177871 .lea_symbol = .{ .sym_index = sym.nlist_idx },177625 .lea_lazy_sym = lazy_sym,
177872 }, .{}),177626 }, .{}),
177873 .mov => try self.genSetReg(reg, .usize, .{177627 .mov => try self.genSetReg(reg, .usize, .{
177874 .load_symbol = .{ .sym_index = sym.nlist_idx },177628 .lea_lazy_sym = lazy_sym,
177875 }, .{}),177629 }, .{}),
177876 else => unreachable,177630 else => unreachable,
177877 }177631 }
...@@ -177880,8 +177634,13 @@ fn genLazySymbolRef(...@@ -177880,8 +177634,13 @@ fn genLazySymbolRef(
177880 .call => try self.asmRegister(.{ ._, .call }, reg),177634 .call => try self.asmRegister(.{ ._, .call }, reg),
177881 else => unreachable,177635 else => unreachable,
177882 }177636 }
177883 } else {177637 } else switch (tag) {
177884 return self.fail("TODO implement genLazySymbol for x86_64 {s}", .{@tagName(self.bin_file.tag)});177638 .lea, .mov => try self.asmRegisterMemory(.{ ._, tag }, reg.to64(), .{
177639 .base = .{ .lazy_sym = lazy_sym },
177640 .mod = .{ .rm = .{ .size = .qword } },
177641 }),
177642 .call => try self.asmImmediate(.{ ._, .call }, .{ .lazy_sym = lazy_sym }),
177643 else => unreachable,
177885 }177644 }
177886}177645}
177887177646
...@@ -178034,11 +177793,11 @@ fn airFloatFromInt(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -178034,11 +177793,11 @@ fn airFloatFromInt(self: *CodeGen, inst: Air.Inst.Index) !void {
178034 src_ty.fmt(pt), dst_ty.fmt(pt),177793 src_ty.fmt(pt), dst_ty.fmt(pt),
178035 });177794 });
178036177795
178037 var callee_buf: ["__floatun?i?f".len]u8 = undefined;177796 var sym_buf: ["__floatun?i?f".len]u8 = undefined;
178038 break :result try self.genCall(.{ .lib = .{177797 break :result try self.genCall(.{ .extern_func = .{
178039 .return_type = dst_ty.toIntern(),177798 .return_type = dst_ty.toIntern(),
178040 .param_types = &.{src_ty.toIntern()},177799 .param_types = &.{src_ty.toIntern()},
178041 .callee = std.fmt.bufPrint(&callee_buf, "__float{s}{c}i{c}f", .{177800 .sym = std.fmt.bufPrint(&sym_buf, "__float{s}{c}i{c}f", .{
178042 switch (src_signedness) {177801 switch (src_signedness) {
178043 .signed => "",177802 .signed => "",
178044 .unsigned => "un",177803 .unsigned => "un",
...@@ -178114,11 +177873,11 @@ fn airIntFromFloat(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -178114,11 +177873,11 @@ fn airIntFromFloat(self: *CodeGen, inst: Air.Inst.Index) !void {
178114 src_ty.fmt(pt), dst_ty.fmt(pt),177873 src_ty.fmt(pt), dst_ty.fmt(pt),
178115 });177874 });
178116177875
178117 var callee_buf: ["__fixuns?f?i".len]u8 = undefined;177876 var sym_buf: ["__fixuns?f?i".len]u8 = undefined;
178118 break :result try self.genCall(.{ .lib = .{177877 break :result try self.genCall(.{ .extern_func = .{
178119 .return_type = dst_ty.toIntern(),177878 .return_type = dst_ty.toIntern(),
178120 .param_types = &.{src_ty.toIntern()},177879 .param_types = &.{src_ty.toIntern()},
178121 .callee = std.fmt.bufPrint(&callee_buf, "__fix{s}{c}f{c}i", .{177880 .sym = std.fmt.bufPrint(&sym_buf, "__fix{s}{c}f{c}i", .{
178122 switch (dst_signedness) {177881 switch (dst_signedness) {
178123 .signed => "",177882 .signed => "",
178124 .unsigned => "uns",177883 .unsigned => "uns",
...@@ -178219,9 +177978,9 @@ fn airCmpxchg(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -178219,9 +177978,9 @@ fn airCmpxchg(self: *CodeGen, inst: Air.Inst.Index) !void {
178219 .off => return self.fail("TODO airCmpxchg with {s}", .{@tagName(ptr_mcv)}),177978 .off => return self.fail("TODO airCmpxchg with {s}", .{@tagName(ptr_mcv)}),
178220 }177979 }
178221 const ptr_lock = switch (ptr_mem.base) {177980 const ptr_lock = switch (ptr_mem.base) {
178222 .none, .frame, .reloc, .pcrel => null,177981 .none, .frame, .nav, .uav => null,
178223 .reg => |reg| self.register_manager.lockReg(reg),177982 .reg => |reg| self.register_manager.lockReg(reg),
178224 .table, .rip_inst => unreachable,177983 .table, .rip_inst, .lazy_sym, .extern_func => unreachable,
178225 };177984 };
178226 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);177985 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);
178227177986
...@@ -178302,9 +178061,9 @@ fn atomicOp(...@@ -178302,9 +178061,9 @@ fn atomicOp(
178302 .off => return self.fail("TODO airCmpxchg with {s}", .{@tagName(ptr_mcv)}),178061 .off => return self.fail("TODO airCmpxchg with {s}", .{@tagName(ptr_mcv)}),
178303 }178062 }
178304 const mem_lock = switch (ptr_mem.base) {178063 const mem_lock = switch (ptr_mem.base) {
178305 .none, .frame, .reloc, .pcrel => null,178064 .none, .frame, .nav, .uav => null,
178306 .reg => |reg| self.register_manager.lockReg(reg),178065 .reg => |reg| self.register_manager.lockReg(reg),
178307 .table, .rip_inst => unreachable,178066 .table, .rip_inst, .lazy_sym, .extern_func => unreachable,
178308 };178067 };
178309 defer if (mem_lock) |lock| self.register_manager.unlockReg(lock);178068 defer if (mem_lock) |lock| self.register_manager.unlockReg(lock);
178310178069
...@@ -179693,7 +179452,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -179693,7 +179452,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void {
179693 var mask_elems_buf: [32]u8 = undefined;179452 var mask_elems_buf: [32]u8 = undefined;
179694 const mask_elems = mask_elems_buf[0..mask_len];179453 const mask_elems = mask_elems_buf[0..mask_len];
179695 for (mask_elems, 0..) |*elem, bit| elem.* = @intCast(bit / elem_bits);179454 for (mask_elems, 0..) |*elem, bit| elem.* = @intCast(bit / elem_bits);
179696 const mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{179455 const mask_mcv = try self.lowerValue(.fromInterned(try pt.intern(.{ .aggregate = .{
179697 .ty = mask_ty.toIntern(),179456 .ty = mask_ty.toIntern(),
179698 .storage = .{ .bytes = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, mask_elems, .maybe_embedded_nulls) },179457 .storage = .{ .bytes = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, mask_elems, .maybe_embedded_nulls) },
179699 } })));179458 } })));
...@@ -179721,7 +179480,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -179721,7 +179480,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void {
179721 mask_elem_ty,179480 mask_elem_ty,
179722 @as(u8, 1) << @truncate(bit),179481 @as(u8, 1) << @truncate(bit),
179723 )).toIntern();179482 )).toIntern();
179724 const mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{179483 const mask_mcv = try self.lowerValue(.fromInterned(try pt.intern(.{ .aggregate = .{
179725 .ty = mask_ty.toIntern(),179484 .ty = mask_ty.toIntern(),
179726 .storage = .{ .elems = mask_elems },179485 .storage = .{ .elems = mask_elems },
179727 } })));179486 } })));
...@@ -180452,7 +180211,7 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -180452,7 +180211,7 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void {
180452 else180211 else
180453 try select_mask_elem_ty.minIntScalar(pt, select_mask_elem_ty)).toIntern();180212 try select_mask_elem_ty.minIntScalar(pt, select_mask_elem_ty)).toIntern();
180454 }180213 }
180455 const select_mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{180214 const select_mask_mcv = try self.lowerValue(.fromInterned(try pt.intern(.{ .aggregate = .{
180456 .ty = select_mask_ty.toIntern(),180215 .ty = select_mask_ty.toIntern(),
180457 .storage = .{ .elems = select_mask_elems[0..mask_elems.len] },180216 .storage = .{ .elems = select_mask_elems[0..mask_elems.len] },
180458 } })));180217 } })));
...@@ -180597,7 +180356,7 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -180597,7 +180356,7 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void {
180597 })).toIntern();180356 })).toIntern();
180598 }180357 }
180599 const lhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type });180358 const lhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type });
180600 const lhs_mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{180359 const lhs_mask_mcv = try self.lowerValue(.fromInterned(try pt.intern(.{ .aggregate = .{
180601 .ty = lhs_mask_ty.toIntern(),180360 .ty = lhs_mask_ty.toIntern(),
180602 .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] },180361 .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] },
180603 } })));180362 } })));
...@@ -180628,7 +180387,7 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -180628,7 +180387,7 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void {
180628 })).toIntern();180387 })).toIntern();
180629 }180388 }
180630 const rhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type });180389 const rhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type });
180631 const rhs_mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{180390 const rhs_mask_mcv = try self.lowerValue(.fromInterned(try pt.intern(.{ .aggregate = .{
180632 .ty = rhs_mask_ty.toIntern(),180391 .ty = rhs_mask_ty.toIntern(),
180633 .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] },180392 .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] },
180634 } })));180393 } })));
...@@ -180962,7 +180721,7 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -180962,7 +180721,7 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void {
180962 .{ .frame = frame_index },180721 .{ .frame = frame_index },
180963 @intCast(elem_size * elements.len),180722 @intCast(elem_size * elements.len),
180964 elem_ty,180723 elem_ty,
180965 try self.genTypedValue(sentinel),180724 try self.lowerValue(sentinel),
180966 .{},180725 .{},
180967 );180726 );
180968 break :result .{ .load_frame = .{ .index = frame_index } };180727 break :result .{ .load_frame = .{ .index = frame_index } };
...@@ -181046,11 +180805,11 @@ fn airMulAdd(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -181046,11 +180805,11 @@ fn airMulAdd(self: *CodeGen, inst: Air.Inst.Index) !void {
181046 ty.fmt(pt),180805 ty.fmt(pt),
181047 });180806 });
181048180807
181049 var callee_buf: ["__fma?".len]u8 = undefined;180808 var sym_buf: ["__fma?".len]u8 = undefined;
181050 break :result try self.genCall(.{ .lib = .{180809 break :result try self.genCall(.{ .extern_func = .{
181051 .return_type = ty.toIntern(),180810 .return_type = ty.toIntern(),
181052 .param_types = &.{ ty.toIntern(), ty.toIntern(), ty.toIntern() },180811 .param_types = &.{ ty.toIntern(), ty.toIntern(), ty.toIntern() },
181053 .callee = std.fmt.bufPrint(&callee_buf, "{s}fma{s}", .{180812 .sym = std.fmt.bufPrint(&sym_buf, "{s}fma{s}", .{
181054 floatLibcAbiPrefix(ty),180813 floatLibcAbiPrefix(ty),
181055 floatLibcAbiSuffix(ty),180814 floatLibcAbiSuffix(ty),
181056 }) catch unreachable,180815 }) catch unreachable,
...@@ -181450,7 +181209,7 @@ fn resolveInst(self: *CodeGen, ref: Air.Inst.Ref) InnerError!MCValue {...@@ -181450,7 +181209,7 @@ fn resolveInst(self: *CodeGen, ref: Air.Inst.Ref) InnerError!MCValue {
181450 const mcv: MCValue = if (ref.toIndex()) |inst| mcv: {181209 const mcv: MCValue = if (ref.toIndex()) |inst| mcv: {
181451 break :mcv self.inst_tracking.getPtr(inst).?.short;181210 break :mcv self.inst_tracking.getPtr(inst).?.short;
181452 } else mcv: {181211 } else mcv: {
181453 break :mcv try self.genTypedValue(.fromInterned(ref.toInterned().?));181212 break :mcv try self.lowerValue(.fromInterned(ref.toInterned().?));
181454 };181213 };
181455181214
181456 switch (mcv) {181215 switch (mcv) {
...@@ -181488,33 +181247,20 @@ fn limitImmediateType(self: *CodeGen, operand: Air.Inst.Ref, comptime T: type) !...@@ -181488,33 +181247,20 @@ fn limitImmediateType(self: *CodeGen, operand: Air.Inst.Ref, comptime T: type) !
181488 return mcv;181247 return mcv;
181489}181248}
181490181249
181491fn genResult(self: *CodeGen, res: codegen.GenResult) InnerError!MCValue {181250fn lowerValue(cg: *CodeGen, val: Value) Allocator.Error!MCValue {
181492 return switch (res) {181251 return switch (try codegen.lowerValue(cg.pt, val, cg.target)) {
181493 .mcv => |mcv| switch (mcv) {181252 .none => .none,
181494 .none => .none,181253 .undef => .undef,
181495 .undef => .undef,181254 .immediate => |imm| .{ .immediate = imm },
181496 .immediate => |imm| .{ .immediate = imm },181255 .lea_nav => |nav| .{ .lea_nav = nav },
181497 .memory => |addr| .{ .memory = addr },181256 .lea_uav => |uav| .{ .lea_uav = uav },
181498 .load_symbol => |sym_index| .{ .load_symbol = .{ .sym_index = sym_index } },181257 .load_uav => |uav| .{ .load_uav = uav },
181499 .lea_symbol => |sym_index| .{ .lea_symbol = .{ .sym_index = sym_index } },
181500 .load_direct => |sym_index| .{ .load_direct = sym_index },
181501 .lea_direct => |sym_index| .{ .lea_direct = sym_index },
181502 .load_got => |sym_index| .{ .lea_got = sym_index },
181503 },
181504 .fail => |msg| return self.failMsg(msg),
181505 };181258 };
181506}181259}
181507181260
181508fn genTypedValue(self: *CodeGen, val: Value) InnerError!MCValue {
181509 return self.genResult(try codegen.genTypedValue(self.bin_file, self.pt, self.src_loc, val, self.target.*));
181510}
181511
181512fn lowerUav(self: *CodeGen, val: Value, alignment: InternPool.Alignment) InnerError!MCValue {
181513 return self.genResult(try self.bin_file.lowerUav(self.pt, val.toIntern(), alignment, self.src_loc));
181514}
181515
181516const CallMCValues = struct {181261const CallMCValues = struct {
181517 args: []MCValue,181262 args: []MCValue,
181263 air_arg_count: u32,
181518 return_value: InstTracking,181264 return_value: InstTracking,
181519 stack_byte_count: u31,181265 stack_byte_count: u31,
181520 stack_align: InternPool.Alignment,181266 stack_align: InternPool.Alignment,
...@@ -181550,13 +181296,14 @@ fn resolveCallingConventionValues(...@@ -181550,13 +181296,14 @@ fn resolveCallingConventionValues(
181550 const param_types = try allocator.alloc(Type, fn_info.param_types.len + var_args.len);181296 const param_types = try allocator.alloc(Type, fn_info.param_types.len + var_args.len);
181551 defer allocator.free(param_types);181297 defer allocator.free(param_types);
181552181298
181553 for (param_types[0..fn_info.param_types.len], fn_info.param_types.get(ip)) |*dest, src|181299 for (param_types[0..fn_info.param_types.len], fn_info.param_types.get(ip)) |*param_ty, arg_ty|
181554 dest.* = .fromInterned(src);181300 param_ty.* = .fromInterned(arg_ty);
181555 for (param_types[fn_info.param_types.len..], var_args) |*param_ty, arg_ty|181301 for (param_types[fn_info.param_types.len..], var_args) |*param_ty, arg_ty|
181556 param_ty.* = self.promoteVarArg(arg_ty);181302 param_ty.* = self.promoteVarArg(arg_ty);
181557181303
181558 var result: CallMCValues = .{181304 var result: CallMCValues = .{
181559 .args = try self.gpa.alloc(MCValue, param_types.len),181305 .args = try self.gpa.alloc(MCValue, param_types.len),
181306 .air_arg_count = 0,
181560 // These undefined values must be populated before returning from this function.181307 // These undefined values must be populated before returning from this function.
181561 .return_value = undefined,181308 .return_value = undefined,
181562 .stack_byte_count = 0,181309 .stack_byte_count = 0,
...@@ -181678,6 +181425,7 @@ fn resolveCallingConventionValues(...@@ -181678,6 +181425,7 @@ fn resolveCallingConventionValues(
181678 // Input params181425 // Input params
181679 for (param_types, result.args) |ty, *arg| {181426 for (param_types, result.args) |ty, *arg| {
181680 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));181427 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
181428 result.air_arg_count += 1;
181681 switch (cc) {181429 switch (cc) {
181682 .x86_64_sysv => {},181430 .x86_64_sysv => {},
181683 .x86_64_win => {181431 .x86_64_win => {
...@@ -181850,6 +181598,7 @@ fn resolveCallingConventionValues(...@@ -181850,6 +181598,7 @@ fn resolveCallingConventionValues(
181850 arg.* = .none;181598 arg.* = .none;
181851 continue;181599 continue;
181852 }181600 }
181601 result.air_arg_count += 1;
181853 const param_size: u31 = @intCast(param_ty.abiSize(zcu));181602 const param_size: u31 = @intCast(param_ty.abiSize(zcu));
181854 if (abi.zigcc.params_in_regs) switch (self.regClassForType(param_ty)) {181603 if (abi.zigcc.params_in_regs) switch (self.regClassForType(param_ty)) {
181855 .general_purpose, .gphi => if (param_gpr.len >= 1 and param_size <= @as(u4, switch (self.target.cpu.arch) {181604 .general_purpose, .gphi => if (param_gpr.len >= 1 and param_size <= @as(u4, switch (self.target.cpu.arch) {
...@@ -182373,16 +182122,16 @@ const Temp = struct {...@@ -182373,16 +182122,16 @@ const Temp = struct {
182373 .register_offset,182122 .register_offset,
182374 .register_mask,182123 .register_mask,
182375 .memory,182124 .memory,
182376 .load_symbol,
182377 .lea_symbol,
182378 .load_pcrel,
182379 .lea_pcrel,
182380 .indirect,182125 .indirect,
182381 .load_direct,
182382 .lea_direct,
182383 .load_got,
182384 .lea_got,
182385 .lea_frame,182126 .lea_frame,
182127 .load_nav,
182128 .lea_nav,
182129 .load_uav,
182130 .lea_uav,
182131 .load_lazy_sym,
182132 .lea_lazy_sym,
182133 .lea_extern_func,
182134 .load_extern_func,
182386 .elementwise_args,182135 .elementwise_args,
182387 .reserved_frame,182136 .reserved_frame,
182388 .air_ref,182137 .air_ref,
...@@ -182425,15 +182174,11 @@ const Temp = struct {...@@ -182425,15 +182174,11 @@ const Temp = struct {
182425 .mod = .{ .rm = .{ .disp = reg_off.off + off } },182174 .mod = .{ .rm = .{ .disp = reg_off.off + off } },
182426 });182175 });
182427 },182176 },
182428 .load_symbol, .load_frame => {182177 .load_frame, .load_nav, .lea_nav, .load_uav, .lea_uav, .load_lazy_sym, .lea_lazy_sym => {
182429 const new_reg = try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp);182178 const new_reg = try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp);
182430 new_temp_index.tracking(cg).* = .init(.{ .register_offset = .{ .reg = new_reg, .off = off } });182179 new_temp_index.tracking(cg).* = .init(.{ .register_offset = .{ .reg = new_reg, .off = off } });
182431 try cg.genSetReg(new_reg, .usize, mcv, .{});182180 try cg.genSetReg(new_reg, .usize, mcv, .{});
182432 },182181 },
182433 .lea_symbol => |sym_off| new_temp_index.tracking(cg).* = .init(.{ .lea_symbol = .{
182434 .sym_index = sym_off.sym_index,
182435 .off = sym_off.off + off,
182436 } }),
182437 .lea_frame => |frame_addr| new_temp_index.tracking(cg).* = .init(.{ .lea_frame = .{182182 .lea_frame => |frame_addr| new_temp_index.tracking(cg).* = .init(.{ .lea_frame = .{
182438 .index = frame_addr.index,182183 .index = frame_addr.index,
182439 .off = frame_addr.off + off,182184 .off = frame_addr.off + off,
...@@ -182466,14 +182211,6 @@ const Temp = struct {...@@ -182466,14 +182211,6 @@ const Temp = struct {
182466 } });182211 } });
182467 return;182212 return;
182468 },182213 },
182469 .lea_symbol => |sym_off| {
182470 assert(std.meta.eql(temp_tracking.long.lea_symbol, sym_off));
182471 temp_tracking.* = .init(.{ .lea_symbol = .{
182472 .sym_index = sym_off.sym_index,
182473 .off = sym_off.off + off,
182474 } });
182475 return;
182476 },
182477 .lea_frame => |frame_addr| {182214 .lea_frame => |frame_addr| {
182478 assert(std.meta.eql(temp_tracking.long.lea_frame, frame_addr));182215 assert(std.meta.eql(temp_tracking.long.lea_frame, frame_addr));
182479 temp_tracking.* = .init(.{ .lea_frame = .{182216 temp_tracking.* = .init(.{ .lea_frame = .{
...@@ -182522,53 +182259,85 @@ const Temp = struct {...@@ -182522,53 +182259,85 @@ const Temp = struct {
182522 .mod = .{ .rm = .{ .disp = reg_off.off + @as(u31, limb_index) * 8 } },182259 .mod = .{ .rm = .{ .disp = reg_off.off + @as(u31, limb_index) * 8 } },
182523 });182260 });
182524 },182261 },
182525 .load_symbol => |sym_off| {182262 .load_frame => |frame_addr| {
182263 const new_reg =
182264 try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp);
182265 new_temp_index.tracking(cg).* = .init(.{ .register = new_reg });
182266 try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{
182267 .base = .{ .frame = frame_addr.index },
182268 .mod = .{ .rm = .{
182269 .size = .qword,
182270 .disp = frame_addr.off + @as(u31, limb_index) * 8,
182271 } },
182272 });
182273 },
182274 .lea_frame => |frame_addr| {
182275 assert(limb_index == 0);
182276 new_temp_index.tracking(cg).* = .init(.{ .lea_frame = frame_addr });
182277 },
182278 .load_nav => |nav| {
182526 const new_reg =182279 const new_reg =
182527 try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp);182280 try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp);
182528 new_temp_index.tracking(cg).* = .init(.{ .register = new_reg });182281 new_temp_index.tracking(cg).* = .init(.{ .register = new_reg });
182529 try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{182282 try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{
182530 .base = .{ .reloc = sym_off.sym_index },182283 .base = .{ .nav = nav },
182531 .mod = .{ .rm = .{182284 .mod = .{ .rm = .{
182532 .size = .qword,182285 .size = .qword,
182533 .disp = sym_off.off + @as(u31, limb_index) * 8,182286 .disp = @as(u31, limb_index) * 8,
182534 } },182287 } },
182535 });182288 });
182536 },182289 },
182537 .lea_symbol => |sym_off| {182290 .lea_nav => |nav| {
182538 assert(limb_index == 0);182291 assert(limb_index == 0);
182539 new_temp_index.tracking(cg).* = .init(.{ .lea_symbol = sym_off });182292 new_temp_index.tracking(cg).* = .init(.{ .lea_nav = nav });
182540 },182293 },
182541 .load_pcrel => |sym_off| {182294 .load_uav => |uav| {
182542 const new_reg =182295 const new_reg =
182543 try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp);182296 try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp);
182544 new_temp_index.tracking(cg).* = .init(.{ .register = new_reg });182297 new_temp_index.tracking(cg).* = .init(.{ .register = new_reg });
182545 try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{182298 try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{
182546 .base = .{ .pcrel = sym_off.sym_index },182299 .base = .{ .uav = uav },
182547 .mod = .{ .rm = .{182300 .mod = .{ .rm = .{
182548 .size = .qword,182301 .size = .qword,
182549 .disp = sym_off.off + @as(u31, limb_index) * 8,182302 .disp = @as(u31, limb_index) * 8,
182550 } },182303 } },
182551 });182304 });
182552 },182305 },
182553 .lea_pcrel => |sym_off| {182306 .lea_uav => |uav| {
182554 assert(limb_index == 0);182307 assert(limb_index == 0);
182555 new_temp_index.tracking(cg).* = .init(.{ .lea_pcrel = sym_off });182308 new_temp_index.tracking(cg).* = .init(.{ .lea_uav = uav });
182556 },182309 },
182557 .load_frame => |frame_addr| {182310 .load_lazy_sym => |lazy_sym| {
182558 const new_reg =182311 const new_reg =
182559 try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp);182312 try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp);
182560 new_temp_index.tracking(cg).* = .init(.{ .register = new_reg });182313 new_temp_index.tracking(cg).* = .init(.{ .register = new_reg });
182561 try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{182314 try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{
182562 .base = .{ .frame = frame_addr.index },182315 .base = .{ .lazy_sym = lazy_sym },
182563 .mod = .{ .rm = .{182316 .mod = .{ .rm = .{
182564 .size = .qword,182317 .size = .qword,
182565 .disp = frame_addr.off + @as(u31, limb_index) * 8,182318 .disp = @as(u31, limb_index) * 8,
182566 } },182319 } },
182567 });182320 });
182568 },182321 },
182569 .lea_frame => |frame_addr| {182322 .lea_lazy_sym => |lazy_sym| {
182570 assert(limb_index == 0);182323 assert(limb_index == 0);
182571 new_temp_index.tracking(cg).* = .init(.{ .lea_frame = frame_addr });182324 new_temp_index.tracking(cg).* = .init(.{ .lea_lazy_sym = lazy_sym });
182325 },
182326 .load_extern_func => |extern_func| {
182327 const new_reg =
182328 try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp);
182329 new_temp_index.tracking(cg).* = .init(.{ .register = new_reg });
182330 try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{
182331 .base = .{ .extern_func = extern_func },
182332 .mod = .{ .rm = .{
182333 .size = .qword,
182334 .disp = @as(u31, limb_index) * 8,
182335 } },
182336 });
182337 },
182338 .lea_extern_func => |extern_func| {
182339 assert(limb_index == 0);
182340 new_temp_index.tracking(cg).* = .init(.{ .lea_extern_func = extern_func });
182572 },182341 },
182573 }182342 }
182574 cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1);182343 cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1);
...@@ -182625,7 +182394,7 @@ const Temp = struct {...@@ -182625,7 +182394,7 @@ const Temp = struct {
182625 const temp_tracking = temp_index.tracking(cg);182394 const temp_tracking = temp_index.tracking(cg);
182626 switch (temp_tracking.short) {182395 switch (temp_tracking.short) {
182627 else => {},182396 else => {},
182628 .register, .lea_symbol, .lea_frame => {182397 .register, .lea_frame, .lea_nav, .lea_uav, .lea_lazy_sym => {
182629 assert(limb_index == 0);182398 assert(limb_index == 0);
182630 cg.temp_type[@intFromEnum(temp_index)] = limb_ty;182399 cg.temp_type[@intFromEnum(temp_index)] = limb_ty;
182631 return;182400 return;
...@@ -182642,15 +182411,6 @@ const Temp = struct {...@@ -182642,15 +182411,6 @@ const Temp = struct {
182642 cg.temp_type[@intFromEnum(temp_index)] = limb_ty;182411 cg.temp_type[@intFromEnum(temp_index)] = limb_ty;
182643 return;182412 return;
182644 },182413 },
182645 .load_symbol => |sym_off| {
182646 assert(std.meta.eql(temp_tracking.long.load_symbol, sym_off));
182647 temp_tracking.* = .init(.{ .load_symbol = .{
182648 .sym_index = sym_off.sym_index,
182649 .off = sym_off.off + @as(u31, limb_index) * 8,
182650 } });
182651 cg.temp_type[@intFromEnum(temp_index)] = limb_ty;
182652 return;
182653 },
182654 .load_frame => |frame_addr| if (!frame_addr.index.isNamed()) {182414 .load_frame => |frame_addr| if (!frame_addr.index.isNamed()) {
182655 assert(std.meta.eql(temp_tracking.long.load_frame, frame_addr));182415 assert(std.meta.eql(temp_tracking.long.load_frame, frame_addr));
182656 temp_tracking.* = .init(.{ .load_frame = .{182416 temp_tracking.* = .init(.{ .load_frame = .{
...@@ -182841,27 +182601,20 @@ const Temp = struct {...@@ -182841,27 +182601,20 @@ const Temp = struct {
182841 .immediate,182601 .immediate,
182842 .register,182602 .register,
182843 .register_offset,182603 .register_offset,
182844 .lea_direct,
182845 .lea_got,
182846 .lea_frame,182604 .lea_frame,
182847 => return false,182605 => return false,
182848 .memory,182606 .memory,
182849 .indirect,182607 .indirect,
182850 .load_symbol,
182851 .load_pcrel,
182852 .load_direct,
182853 .load_got,
182854 .load_frame,182608 .load_frame,
182609 .load_nav,
182610 .lea_nav,
182611 .load_uav,
182612 .lea_uav,
182613 .load_lazy_sym,
182614 .lea_lazy_sym,
182615 .load_extern_func,
182616 .lea_extern_func,
182855 => return temp.toRegClass(true, .general_purpose, cg),182617 => return temp.toRegClass(true, .general_purpose, cg),
182856 .lea_symbol, .lea_pcrel => |sym_off| {
182857 const off = sym_off.off;
182858 // hack around linker relocation bugs
182859 if (false and off == 0) return false;
182860 try temp.toOffset(-off, cg);
182861 while (try temp.toRegClass(true, .general_purpose, cg)) {}
182862 try temp.toOffset(off, cg);
182863 return true;
182864 },
182865 }182618 }
182866 }182619 }
182867182620
...@@ -182928,7 +182681,7 @@ const Temp = struct {...@@ -182928,7 +182681,7 @@ const Temp = struct {
182928 ), cg),182681 ), cg),
182929 else => unreachable,182682 else => unreachable,
182930 },182683 },
182931 .memory, .indirect, .load_frame, .load_symbol => {182684 .memory, .indirect, .load_frame, .load_nav, .load_uav, .load_lazy_sym => {
182932 var val_ptr = try cg.tempInit(.usize, val_mcv.address());182685 var val_ptr = try cg.tempInit(.usize, val_mcv.address());
182933 var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) });182686 var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) });
182934 try val_ptr.memcpy(ptr, &len, cg);182687 try val_ptr.memcpy(ptr, &len, cg);
...@@ -182966,7 +182719,11 @@ const Temp = struct {...@@ -182966,7 +182719,11 @@ const Temp = struct {
182966 // hack around linker relocation bugs182719 // hack around linker relocation bugs
182967 switch (ptr.tracking(cg).short) {182720 switch (ptr.tracking(cg).short) {
182968 else => {},182721 else => {},
182969 .lea_symbol => while (try ptr.toRegClass(false, .general_purpose, cg)) {},182722 .lea_nav,
182723 .lea_uav,
182724 .lea_lazy_sym,
182725 .lea_extern_func,
182726 => while (try ptr.toRegClass(false, .general_purpose, cg)) {},
182970 }182727 }
182971 try cg.asmMemoryImmediate(182728 try cg.asmMemoryImmediate(
182972 .{ ._, .mov },182729 .{ ._, .mov },
...@@ -182980,7 +182737,11 @@ const Temp = struct {...@@ -182980,7 +182737,11 @@ const Temp = struct {
182980 // hack around linker relocation bugs182737 // hack around linker relocation bugs
182981 switch (ptr.tracking(cg).short) {182738 switch (ptr.tracking(cg).short) {
182982 else => {},182739 else => {},
182983 .lea_symbol => while (try ptr.toRegClass(false, .general_purpose, cg)) {},182740 .lea_nav,
182741 .lea_uav,
182742 .lea_lazy_sym,
182743 .lea_extern_func,
182744 => while (try ptr.toRegClass(false, .general_purpose, cg)) {},
182984 }182745 }
182985 try cg.asmSetccMemory(182746 try cg.asmSetccMemory(
182986 cc,182747 cc,
...@@ -183024,8 +182785,8 @@ const Temp = struct {...@@ -183024,8 +182785,8 @@ const Temp = struct {
183024 try ptr.tracking(cg).short.deref().mem(cg, .{ .size = .byte }),182785 try ptr.tracking(cg).short.deref().mem(cg, .{ .size = .byte }),
183025 );182786 );
183026 },182787 },
183027 .lea_frame, .lea_symbol => continue :val_to_gpr,182788 .lea_frame, .lea_nav, .lea_uav, .lea_lazy_sym => continue :val_to_gpr,
183028 .memory, .indirect, .load_frame, .load_symbol => {182789 .memory, .indirect, .load_frame, .load_nav, .load_uav, .load_lazy_sym => {
183029 var val_ptr = try cg.tempInit(.usize, val_mcv.address());182790 var val_ptr = try cg.tempInit(.usize, val_mcv.address());
183030 var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) });182791 var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) });
183031 try ptr.memcpy(&val_ptr, &len, cg);182792 try ptr.memcpy(&val_ptr, &len, cg);
...@@ -183065,7 +182826,7 @@ const Temp = struct {...@@ -183065,7 +182826,7 @@ const Temp = struct {
183065 ), cg),182826 ), cg),
183066 else => unreachable,182827 else => unreachable,
183067 },182828 },
183068 .memory, .indirect, .load_frame, .load_symbol => {182829 .memory, .indirect, .load_frame, .load_nav, .load_uav, .load_lazy_sym => {
183069 var val_ptr = try cg.tempInit(.usize, val_mcv.address());182830 var val_ptr = try cg.tempInit(.usize, val_mcv.address());
183070 var src_ptr =182831 var src_ptr =
183071 try cg.tempInit(.usize, src.tracking(cg).short.address().offset(opts.disp));182832 try cg.tempInit(.usize, src.tracking(cg).short.address().offset(opts.disp));
...@@ -183159,8 +182920,8 @@ const Temp = struct {...@@ -183159,8 +182920,8 @@ const Temp = struct {
183159 }),182920 }),
183160 );182921 );
183161 },182922 },
183162 .lea_frame, .lea_symbol => continue :val_to_gpr,182923 .lea_frame, .lea_nav, .lea_uav, .lea_lazy_sym => continue :val_to_gpr,
183163 .memory, .indirect, .load_frame, .load_symbol => {182924 .memory, .indirect, .load_frame, .load_nav, .load_uav, .load_lazy_sym => {
183164 var dst_ptr =182925 var dst_ptr =
183165 try cg.tempInit(.usize, dst.tracking(cg).short.address().offset(opts.disp));182926 try cg.tempInit(.usize, dst.tracking(cg).short.address().offset(opts.disp));
183166 var val_ptr = try cg.tempInit(.usize, val_mcv.address());182927 var val_ptr = try cg.tempInit(.usize, val_mcv.address());
...@@ -183181,7 +182942,7 @@ const Temp = struct {...@@ -183181,7 +182942,7 @@ const Temp = struct {
183181 // hack around linker relocation bugs182942 // hack around linker relocation bugs
183182 switch (ptr.tracking(cg).short) {182943 switch (ptr.tracking(cg).short) {
183183 else => {},182944 else => {},
183184 .lea_symbol => |sym_off| if (dst_rc != .general_purpose or sym_off.off != 0)182945 .lea_nav, .lea_uav, .lea_lazy_sym => if (dst_rc != .general_purpose)
183185 while (try ptr.toRegClass(false, .general_purpose, cg)) {},182946 while (try ptr.toRegClass(false, .general_purpose, cg)) {},
183186 }182947 }
183187 try strat.read(cg, dst_reg, try ptr.tracking(cg).short.deref().mem(cg, .{182948 try strat.read(cg, dst_reg, try ptr.tracking(cg).short.deref().mem(cg, .{
...@@ -183201,7 +182962,7 @@ const Temp = struct {...@@ -183201,7 +182962,7 @@ const Temp = struct {
183201 // hack around linker relocation bugs182962 // hack around linker relocation bugs
183202 switch (ptr.tracking(cg).short) {182963 switch (ptr.tracking(cg).short) {
183203 else => {},182964 else => {},
183204 .lea_symbol => while (try ptr.toRegClass(false, .general_purpose, cg)) {},182965 .lea_nav, .lea_uav, .lea_lazy_sym => while (try ptr.toRegClass(false, .general_purpose, cg)) {},
183205 }182966 }
183206 const strat = try cg.moveStrategy(src_ty, src_rc, false);182967 const strat = try cg.moveStrategy(src_ty, src_rc, false);
183207 try strat.write(cg, try ptr.tracking(cg).short.deref().mem(cg, .{182968 try strat.write(cg, try ptr.tracking(cg).short.deref().mem(cg, .{
...@@ -186964,7 +186725,7 @@ const Temp = struct {...@@ -186964,7 +186725,7 @@ const Temp = struct {
186964 },186725 },
186965 .call_frame = .{ .alignment = .@"16" },186726 .call_frame = .{ .alignment = .@"16" },
186966 .extra_temps = .{186727 .extra_temps = .{
186967 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divti3" } } },186728 .{ .type = .usize, .kind = .{ .extern_func = "__divti3" } },
186968 .unused,186729 .unused,
186969 .unused,186730 .unused,
186970 .unused,186731 .unused,
...@@ -186993,7 +186754,7 @@ const Temp = struct {...@@ -186993,7 +186754,7 @@ const Temp = struct {
186993 },186754 },
186994 .call_frame = .{ .alignment = .@"16" },186755 .call_frame = .{ .alignment = .@"16" },
186995 .extra_temps = .{186756 .extra_temps = .{
186996 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__udivti3" } } },186757 .{ .type = .usize, .kind = .{ .extern_func = "__udivti3" } },
186997 .unused,186758 .unused,
186998 .unused,186759 .unused,
186999 .unused,186760 .unused,
...@@ -187026,7 +186787,7 @@ const Temp = struct {...@@ -187026,7 +186787,7 @@ const Temp = struct {
187026 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },186787 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
187027 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },186788 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
187028 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },186789 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
187029 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divei4" } } },186790 .{ .type = .usize, .kind = .{ .extern_func = "__divei4" } },
187030 .unused,186791 .unused,
187031 .unused,186792 .unused,
187032 .unused,186793 .unused,
...@@ -187059,7 +186820,7 @@ const Temp = struct {...@@ -187059,7 +186820,7 @@ const Temp = struct {
187059 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },186820 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
187060 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },186821 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
187061 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },186822 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
187062 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__udivei4" } } },186823 .{ .type = .usize, .kind = .{ .extern_func = "__udivei4" } },
187063 .unused,186824 .unused,
187064 .unused,186825 .unused,
187065 .unused,186826 .unused,
...@@ -187423,7 +187184,7 @@ const Temp = struct {...@@ -187423,7 +187184,7 @@ const Temp = struct {
187423 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },187184 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
187424 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },187185 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
187425 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },187186 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
187426 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divti3" } } },187187 .{ .type = .usize, .kind = .{ .extern_func = "__divti3" } },
187427 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },187188 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },
187428 .unused,187189 .unused,
187429 .unused,187190 .unused,
...@@ -187461,7 +187222,7 @@ const Temp = struct {...@@ -187461,7 +187222,7 @@ const Temp = struct {
187461 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },187222 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
187462 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },187223 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
187463 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },187224 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
187464 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__udivti3" } } },187225 .{ .type = .usize, .kind = .{ .extern_func = "__udivti3" } },
187465 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },187226 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },
187466 .unused,187227 .unused,
187467 .unused,187228 .unused,
...@@ -187499,7 +187260,7 @@ const Temp = struct {...@@ -187499,7 +187260,7 @@ const Temp = struct {
187499 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },187260 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
187500 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },187261 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
187501 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },187262 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
187502 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divei4" } } },187263 .{ .type = .usize, .kind = .{ .extern_func = "__divei4" } },
187503 .unused,187264 .unused,
187504 .unused,187265 .unused,
187505 .unused,187266 .unused,
...@@ -187535,7 +187296,7 @@ const Temp = struct {...@@ -187535,7 +187296,7 @@ const Temp = struct {
187535 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },187296 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
187536 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },187297 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
187537 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },187298 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
187538 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__udivei4" } } },187299 .{ .type = .usize, .kind = .{ .extern_func = "__udivei4" } },
187539 .unused,187300 .unused,
187540 .unused,187301 .unused,
187541 .unused,187302 .unused,
...@@ -187590,16 +187351,16 @@ const Temp = struct {...@@ -187590,16 +187351,16 @@ const Temp = struct {
187590 .register_overflow,187351 .register_overflow,
187591 .register_mask,187352 .register_mask,
187592 .memory,187353 .memory,
187593 .load_symbol,
187594 .lea_symbol,
187595 .load_pcrel,
187596 .lea_pcrel,
187597 .indirect,187354 .indirect,
187598 .load_direct,
187599 .lea_direct,
187600 .load_got,
187601 .lea_got,
187602 .load_frame,187355 .load_frame,
187356 .load_nav,
187357 .lea_nav,
187358 .load_uav,
187359 .lea_uav,
187360 .load_lazy_sym,
187361 .lea_lazy_sym,
187362 .load_extern_func,
187363 .lea_extern_func,
187603 => {187364 => {
187604 const result = try cg.allocRegOrMem(inst, true);187365 const result = try cg.allocRegOrMem(inst, true);
187605 try cg.genCopy(cg.typeOfIndex(inst), result, temp_mcv, .{});187366 try cg.genCopy(cg.typeOfIndex(inst), result, temp_mcv, .{});
...@@ -187776,7 +187537,7 @@ fn tempInit(cg: *CodeGen, ty: Type, value: MCValue) InnerError!Temp {...@@ -187776,7 +187537,7 @@ fn tempInit(cg: *CodeGen, ty: Type, value: MCValue) InnerError!Temp {
187776}187537}
187777187538
187778fn tempFromValue(cg: *CodeGen, value: Value) InnerError!Temp {187539fn tempFromValue(cg: *CodeGen, value: Value) InnerError!Temp {
187779 return cg.tempInit(value.typeOf(cg.pt.zcu), try cg.genTypedValue(value));187540 return cg.tempInit(value.typeOf(cg.pt.zcu), try cg.lowerValue(value));
187780}187541}
187781187542
187782fn tempMemFromValue(cg: *CodeGen, value: Value) InnerError!Temp {187543fn tempMemFromValue(cg: *CodeGen, value: Value) InnerError!Temp {
...@@ -187784,13 +187545,20 @@ fn tempMemFromValue(cg: *CodeGen, value: Value) InnerError!Temp {...@@ -187784,13 +187545,20 @@ fn tempMemFromValue(cg: *CodeGen, value: Value) InnerError!Temp {
187784}187545}
187785187546
187786fn tempMemFromAlignedValue(cg: *CodeGen, alignment: InternPool.Alignment, value: Value) InnerError!Temp {187547fn tempMemFromAlignedValue(cg: *CodeGen, alignment: InternPool.Alignment, value: Value) InnerError!Temp {
187787 return cg.tempInit(value.typeOf(cg.pt.zcu), try cg.lowerUav(value, alignment));187548 const ty = value.typeOf(cg.pt.zcu);
187549 return cg.tempInit(ty, .{ .load_uav = .{
187550 .val = value.toIntern(),
187551 .orig_ty = (try cg.pt.ptrType(.{
187552 .child = ty.toIntern(),
187553 .flags = .{
187554 .is_const = true,
187555 .alignment = alignment,
187556 },
187557 })).toIntern(),
187558 } });
187788}187559}
187789187560
187790fn tempFromOperand(cg: *CodeGen, op_ref: Air.Inst.Ref, op_dies: bool) InnerError!Temp {187561fn tempFromOperand(cg: *CodeGen, op_ref: Air.Inst.Ref, op_dies: bool) InnerError!Temp {
187791 const zcu = cg.pt.zcu;
187792 const ip = &zcu.intern_pool;
187793
187794 if (op_dies) {187562 if (op_dies) {
187795 const temp_index = cg.next_temp_index;187563 const temp_index = cg.next_temp_index;
187796 const temp: Temp = .{ .index = temp_index.toIndex() };187564 const temp: Temp = .{ .index = temp_index.toIndex() };
...@@ -187804,8 +187572,7 @@ fn tempFromOperand(cg: *CodeGen, op_ref: Air.Inst.Ref, op_dies: bool) InnerError...@@ -187804,8 +187572,7 @@ fn tempFromOperand(cg: *CodeGen, op_ref: Air.Inst.Ref, op_dies: bool) InnerError
187804 }187572 }
187805187573
187806 if (op_ref.toIndex()) |op_inst| return .{ .index = op_inst };187574 if (op_ref.toIndex()) |op_inst| return .{ .index = op_inst };
187807 const val = op_ref.toInterned().?;187575 return cg.tempFromValue(.fromInterned(op_ref.toInterned().?));
187808 return cg.tempInit(.fromInterned(ip.typeOf(val)), try cg.genTypedValue(.fromInterned(val)));
187809}187576}
187810187577
187811fn tempsFromOperandsInner(187578fn tempsFromOperandsInner(
...@@ -188640,8 +188407,8 @@ const Select = struct {...@@ -188640,8 +188407,8 @@ const Select = struct {
188640 splat_int_mem: struct { ref: Select.Operand.Ref, inside: enum { umin, smin, smax } = .umin, outside: enum { smin, smax } },188407 splat_int_mem: struct { ref: Select.Operand.Ref, inside: enum { umin, smin, smax } = .umin, outside: enum { smin, smax } },
188641 splat_float_mem: struct { ref: Select.Operand.Ref, inside: enum { zero } = .zero, outside: f16 },188408 splat_float_mem: struct { ref: Select.Operand.Ref, inside: enum { zero } = .zero, outside: f16 },
188642 frame: FrameIndex,188409 frame: FrameIndex,
188643 lazy_symbol: struct { kind: link.File.LazySymbol.Kind, ref: Select.Operand.Ref = .none },188410 lazy_sym: struct { kind: link.File.LazySymbol.Kind, ref: Select.Operand.Ref = .none },
188644 symbol: *const struct { lib: ?[]const u8 = null, name: []const u8 },188411 extern_func: [*:0]const u8,
188645188412
188646 const ConstSpec = struct {188413 const ConstSpec = struct {
188647 ref: Select.Operand.Ref = .none,188414 ref: Select.Operand.Ref = .none,
...@@ -189072,43 +188839,21 @@ const Select = struct {...@@ -189072,43 +188839,21 @@ const Select = struct {
189072 } }))), true };188839 } }))), true };
189073 },188840 },
189074 .frame => |frame_index| .{ try cg.tempInit(spec.type, .{ .load_frame = .{ .index = frame_index } }), true },188841 .frame => |frame_index| .{ try cg.tempInit(spec.type, .{ .load_frame = .{ .index = frame_index } }), true },
189075 .lazy_symbol => |lazy_symbol_spec| {188842 .lazy_sym => |lazy_symbol_spec| {
189076 const ip = &pt.zcu.intern_pool;188843 const ip = &pt.zcu.intern_pool;
189077 const ty = if (lazy_symbol_spec.ref == .none) spec.type else lazy_symbol_spec.ref.typeOf(s);188844 const ty = if (lazy_symbol_spec.ref == .none) spec.type else lazy_symbol_spec.ref.typeOf(s);
189078 const lazy_symbol: link.File.LazySymbol = .{188845 return .{ try cg.tempInit(.usize, .{ .lea_lazy_sym = .{
189079 .kind = lazy_symbol_spec.kind,188846 .kind = lazy_symbol_spec.kind,
189080 .ty = switch (ip.indexToKey(ty.toIntern())) {188847 .ty = switch (ip.indexToKey(ty.toIntern())) {
189081 .inferred_error_set_type => |func_index| switch (ip.funcIesResolvedUnordered(func_index)) {188848 .inferred_error_set_type => |func_index| switch (ip.funcIesResolvedUnordered(func_index)) {
189082 .none => unreachable, // unresolved inferred error set188849 .none => unreachable,
189083 else => |ty_index| ty_index,188850 else => |ty_index| ty_index,
189084 },188851 },
189085 else => ty.toIntern(),188852 else => ty.toIntern(),
189086 },188853 },
189087 };
189088 return .{ try cg.tempInit(.usize, .{ .lea_symbol = .{
189089 .sym_index = if (cg.bin_file.cast(.elf)) |elf_file|
189090 elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_symbol) catch |err|
189091 return cg.fail("{s} creating lazy symbol", .{@errorName(err)})
189092 else if (cg.bin_file.cast(.macho)) |macho_file|
189093 macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_symbol) catch |err|
189094 return cg.fail("{s} creating lazy symbol", .{@errorName(err)})
189095 else if (cg.bin_file.cast(.coff)) |coff_file|
189096 coff_file.getAtom(coff_file.getOrCreateAtomForLazySymbol(pt, lazy_symbol) catch |err|
189097 return cg.fail("{s} creating lazy symbol", .{@errorName(err)})).getSymbolIndex().?
189098 else
189099 return cg.fail("external symbols unimplemented for {s}", .{@tagName(cg.bin_file.tag)}),
189100 } }), true };188854 } }), true };
189101 },188855 },
189102 .symbol => |symbol_spec| .{ try cg.tempInit(spec.type, .{ .lea_symbol = .{188856 .extern_func => |extern_func_spec| .{ try cg.tempInit(spec.type, .{ .lea_extern_func = try cg.addString(std.mem.span(extern_func_spec)) }), true },
189103 .sym_index = if (cg.bin_file.cast(.elf)) |elf_file|
189104 try elf_file.getGlobalSymbol(symbol_spec.name, symbol_spec.lib)
189105 else if (cg.bin_file.cast(.macho)) |macho_file|
189106 try macho_file.getGlobalSymbol(symbol_spec.name, symbol_spec.lib)
189107 else if (cg.bin_file.cast(.coff)) |coff_file|
189108 link.File.Coff.global_symbol_bit | try coff_file.getGlobalSymbol(symbol_spec.name, symbol_spec.lib)
189109 else
189110 return cg.fail("external symbols unimplemented for {s}", .{@tagName(cg.bin_file.tag)}),
189111 } }), true },
189112 };188857 };
189113 }188858 }
189114188859
...@@ -190151,9 +189896,12 @@ const Select = struct {...@@ -190151,9 +189896,12 @@ const Select = struct {
190151 .register => |reg| .{ .reg = s.lowerReg(reg.toSize(op.flags.base.size, s.cg.target)) },189896 .register => |reg| .{ .reg = s.lowerReg(reg.toSize(op.flags.base.size, s.cg.target)) },
190152 .register_pair, .register_triple, .register_quadruple, .register_offset, .register_overflow => unreachable,189897 .register_pair, .register_triple, .register_quadruple, .register_offset, .register_overflow => unreachable,
190153 .register_mask => |reg_mask| .{ .reg = s.lowerReg(reg_mask.reg.toSize(op.flags.base.size, s.cg.target)) },189898 .register_mask => |reg_mask| .{ .reg = s.lowerReg(reg_mask.reg.toSize(op.flags.base.size, s.cg.target)) },
189899 .lea_nav => |nav| .{ .imm = .{ .nav = .{ .index = nav } } },
189900 .lea_uav => |uav| .{ .imm = .{ .uav = uav } },
189901 .lea_lazy_sym => |lazy_sym| .{ .imm = .{ .lazy_sym = lazy_sym } },
189902 .lea_extern_func => |extern_func| .{ .imm = .{ .extern_func = extern_func } },
190154 else => |mcv| .{ .mem = try mcv.mem(s.cg, .{ .size = op.flags.base.size }) },189903 else => |mcv| .{ .mem = try mcv.mem(s.cg, .{ .size = op.flags.base.size }) },
190155 .lea_symbol => |sym_off| .{ .imm = .rel(sym_off) },189904 .lea_frame, .elementwise_args, .reserved_frame, .air_ref => unreachable,
190156 .load_direct, .lea_direct, .load_got, .lea_got, .lea_frame, .elementwise_args, .reserved_frame, .air_ref => unreachable,
190157 },189905 },
190158 1...2 => |imm| switch (op.flags.base.ref.valueOf(s)) {189906 1...2 => |imm| switch (op.flags.base.ref.valueOf(s)) {
190159 inline .register_pair, .register_triple, .register_quadruple => |regs| .{189907 inline .register_pair, .register_triple, .register_quadruple => |regs| .{
...@@ -190167,37 +189915,20 @@ const Select = struct {...@@ -190167,37 +189915,20 @@ const Select = struct {
190167 },189915 },
190168 .simm => .{ .imm = .s(op.adjustedImm(i32, s)) },189916 .simm => .{ .imm = .s(op.adjustedImm(i32, s)) },
190169 .uimm => .{ .imm = .u(@bitCast(op.adjustedImm(i64, s))) },189917 .uimm => .{ .imm = .u(@bitCast(op.adjustedImm(i64, s))) },
190170 .lea => .{ .mem = .{189918 .lea => .{ .mem = try op.flags.base.ref.valueOf(s).deref().mem(s.cg, .{
190171 .base = switch (op.flags.base.ref.valueOf(s)) {189919 .size = op.flags.base.size,
189920 .index = switch (op.flags.index.ref.valueOf(s)) {
190172 else => unreachable,189921 else => unreachable,
190173 .none => .none,189922 .none => .none,
190174 .register => |base_reg| .{ .reg = base_reg.toSize(.ptr, s.cg.target) },189923 .register => |index_reg| index_reg.toSize(.ptr, s.cg.target),
190175 .register_offset => |base_reg_off| .{ .reg = base_reg_off.reg.toSize(.ptr, s.cg.target) },
190176 .lea_symbol => |base_sym_off| .{ .reloc = base_sym_off.sym_index },
190177 .lea_pcrel => |base_sym_off| .{ .pcrel = base_sym_off.sym_index },
190178 },189924 },
190179 .mod = .{ .rm = .{189925 .scale = op.flags.index.scale,
190180 .size = op.flags.base.size,189926 .disp = op.adjustedImm(i32, s) + switch (op.flags.index.ref.valueOf(s)) {
190181 .index = switch (op.flags.index.ref.valueOf(s)) {189927 else => unreachable,
190182 else => unreachable,189928 .none, .register, .lea_nav, .lea_uav, .lea_lazy_sym, .lea_extern_func => 0,
190183 .none => .none,189929 .register_offset => |base_reg_off| base_reg_off.off,
190184 .register => |index_reg| index_reg.toSize(.ptr, s.cg.target),189930 },
190185 .register_offset => |index_reg_off| index_reg_off.reg.toSize(.ptr, s.cg.target),189931 }) },
190186 },
190187 .scale = op.flags.index.scale,
190188 .disp = op.adjustedImm(i32, s) + switch (op.flags.base.ref.valueOf(s)) {
190189 else => unreachable,
190190 .none, .register => 0,
190191 .register_offset => |base_reg_off| base_reg_off.off,
190192 .lea_symbol => |base_sym_off| base_sym_off.off,
190193 } + switch (op.flags.index.ref.valueOf(s)) {
190194 else => unreachable,
190195 .none, .register => 0,
190196 .register_offset => |base_reg_off| base_reg_off.off,
190197 .lea_symbol => |base_sym_off| base_sym_off.off,
190198 },
190199 } },
190200 } },
190201 .mem => .{ .mem = try op.flags.base.ref.valueOf(s).mem(s.cg, .{189932 .mem => .{ .mem = try op.flags.base.ref.valueOf(s).mem(s.cg, .{
190202 .size = op.flags.base.size,189933 .size = op.flags.base.size,
190203 .index = switch (op.flags.index.ref.valueOf(s)) {189934 .index = switch (op.flags.index.ref.valueOf(s)) {
src/arch/x86_64/Emit.zig+648-290
...@@ -1,7 +1,9 @@...@@ -1,7 +1,9 @@
1//! This file contains the functionality for emitting x86_64 MIR as machine code1//! This file contains the functionality for emitting x86_64 MIR as machine code
22
3air: Air,
4lower: Lower,3lower: Lower,
4bin_file: *link.File,
5pt: Zcu.PerThread,
6pic: bool,
5atom_index: u32,7atom_index: u32,
6debug_output: link.File.DebugInfoOutput,8debug_output: link.File.DebugInfoOutput,
7code: *std.ArrayListUnmanaged(u8),9code: *std.ArrayListUnmanaged(u8),
...@@ -10,26 +12,29 @@ prev_di_loc: Loc,...@@ -10,26 +12,29 @@ prev_di_loc: Loc,
10/// Relative to the beginning of `code`.12/// Relative to the beginning of `code`.
11prev_di_pc: usize,13prev_di_pc: usize,
1214
15code_offset_mapping: std.ArrayListUnmanaged(u32),
16relocs: std.ArrayListUnmanaged(Reloc),
17table_relocs: std.ArrayListUnmanaged(TableReloc),
18
13pub const Error = Lower.Error || error{19pub const Error = Lower.Error || error{
14 EmitFail,20 EmitFail,
15} || link.File.UpdateDebugInfoError;21} || link.File.UpdateDebugInfoError;
1622
17pub fn emitMir(emit: *Emit) Error!void {23pub fn emitMir(emit: *Emit) Error!void {
18 const gpa = emit.lower.bin_file.comp.gpa;24 const comp = emit.bin_file.comp;
19 const code_offset_mapping = try emit.lower.allocator.alloc(u32, emit.lower.mir.instructions.len);25 const gpa = comp.gpa;
20 defer emit.lower.allocator.free(code_offset_mapping);26 try emit.code_offset_mapping.resize(gpa, emit.lower.mir.instructions.len);
21 var relocs: std.ArrayListUnmanaged(Reloc) = .empty;27 emit.relocs.clearRetainingCapacity();
22 defer relocs.deinit(emit.lower.allocator);28 emit.table_relocs.clearRetainingCapacity();
23 var table_relocs: std.ArrayListUnmanaged(TableReloc) = .empty;29 var local_index: usize = 0;
24 defer table_relocs.deinit(emit.lower.allocator);
25 for (0..emit.lower.mir.instructions.len) |mir_i| {30 for (0..emit.lower.mir.instructions.len) |mir_i| {
26 const mir_index: Mir.Inst.Index = @intCast(mir_i);31 const mir_index: Mir.Inst.Index = @intCast(mir_i);
27 code_offset_mapping[mir_index] = @intCast(emit.code.items.len);32 emit.code_offset_mapping.items[mir_index] = @intCast(emit.code.items.len);
28 const lowered = try emit.lower.lowerMir(mir_index);33 const lowered = try emit.lower.lowerMir(mir_index);
29 var lowered_relocs = lowered.relocs;34 var lowered_relocs = lowered.relocs;
30 for (lowered.insts, 0..) |lowered_inst, lowered_index| {35 lowered_inst: for (lowered.insts, 0..) |lowered_inst, lowered_index| {
31 const start_offset: u32 = @intCast(emit.code.items.len);
32 if (lowered_inst.prefix == .directive) {36 if (lowered_inst.prefix == .directive) {
37 const start_offset: u32 = @intCast(emit.code.items.len);
33 switch (emit.debug_output) {38 switch (emit.debug_output) {
34 .dwarf => |dwarf| switch (lowered_inst.encoding.mnemonic) {39 .dwarf => |dwarf| switch (lowered_inst.encoding.mnemonic) {
35 .@".cfi_def_cfa" => try dwarf.genDebugFrame(start_offset, .{ .def_cfa = .{40 .@".cfi_def_cfa" => try dwarf.genDebugFrame(start_offset, .{ .def_cfa = .{
...@@ -82,204 +87,327 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -82,204 +87,327 @@ pub fn emitMir(emit: *Emit) Error!void {
82 }87 }
83 continue;88 continue;
84 }89 }
85 try lowered_inst.encode(emit.code.writer(gpa), .{});90 var reloc_info_buf: [2]RelocInfo = undefined;
86 const end_offset: u32 = @intCast(emit.code.items.len);91 var reloc_info_index: usize = 0;
87 while (lowered_relocs.len > 0 and92 while (lowered_relocs.len > 0 and
88 lowered_relocs[0].lowered_inst_index == lowered_index) : ({93 lowered_relocs[0].lowered_inst_index == lowered_index) : ({
89 lowered_relocs = lowered_relocs[1..];94 lowered_relocs = lowered_relocs[1..];
90 }) switch (lowered_relocs[0].target) {95 reloc_info_index += 1;
91 .inst => |target| {96 }) reloc_info_buf[reloc_info_index] = .{
92 const inst_length: u4 = @intCast(end_offset - start_offset);97 .op_index = lowered_relocs[0].op_index,
93 const reloc_offset, const reloc_length = reloc_offset_length: {98 .off = lowered_relocs[0].off,
94 var reloc_offset = inst_length;99 .target = target: switch (lowered_relocs[0].target) {
95 var op_index: usize = lowered_inst.ops.len;100 .inst => |inst| .{ .index = inst, .is_extern = false, .type = .inst },
96 while (true) {101 .table => .{ .index = undefined, .is_extern = false, .type = .table },
97 op_index -= 1;102 .nav => |nav| {
98 const op = lowered_inst.encoding.data.ops[op_index];103 const sym_index = switch (try codegen.genNavRef(
99 if (op == .none) continue;104 emit.bin_file,
100 const is_mem = op.isMemory();105 emit.pt,
101 const enc_length: u4 = if (is_mem) switch (lowered_inst.ops[op_index].mem.sib.base) {106 emit.lower.src_loc,
102 .rip_inst => 4,107 nav,
103 else => unreachable,108 emit.lower.target.*,
104 } else @intCast(std.math.divCeil(u7, @intCast(op.immBitSize()), 8) catch unreachable);109 )) {
105 reloc_offset -= enc_length;110 .mcv => |mcv| mcv.lea_symbol,
106 if (op_index == lowered_relocs[0].op_index) break :reloc_offset_length .{ reloc_offset, enc_length };111 .fail => |em| {
107 std.debug.assert(!is_mem);112 assert(emit.lower.err_msg == null);
108 }113 emit.lower.err_msg = em;
109 };114 return error.EmitFail;
110 try relocs.append(emit.lower.allocator, .{115 },
111 .inst_offset = start_offset,116 };
112 .inst_length = inst_length,117 const ip = &emit.pt.zcu.intern_pool;
113 .source_offset = reloc_offset,118 break :target switch (ip.getNav(nav).status) {
114 .source_length = reloc_length,119 .unresolved => unreachable,
115 .target = target,120 .type_resolved => |type_resolved| .{
116 .target_offset = lowered_relocs[0].off,121 .index = sym_index,
117 });122 .is_extern = false,
118 },123 .type = if (type_resolved.is_threadlocal and comp.config.any_non_single_threaded) .tlv else .symbol,
119 .table => try table_relocs.append(emit.lower.allocator, .{124 },
120 .source_offset = end_offset - 4,125 .fully_resolved => |fully_resolved| switch (ip.indexToKey(fully_resolved.val)) {
121 .target_offset = lowered_relocs[0].off,126 .@"extern" => |@"extern"| .{
122 }),127 .index = sym_index,
123 .linker_extern_fn => |sym_index| if (emit.lower.bin_file.cast(.elf)) |elf_file| {128 .is_extern = switch (@"extern".visibility) {
124 // Add relocation to the decl.129 .default => true,
125 const zo = elf_file.zigObjectPtr().?;130 .hidden, .protected => false,
126 const atom_ptr = zo.symbol(emit.atom_index).atom(elf_file).?;131 },
127 const r_type = @intFromEnum(std.elf.R_X86_64.PLT32);132 .type = if (@"extern".is_threadlocal and comp.config.any_non_single_threaded) .tlv else .symbol,
128 try atom_ptr.addReloc(gpa, .{133 .force_pcrel_direct = switch (@"extern".relocation) {
129 .r_offset = end_offset - 4,134 .any => false,
130 .r_info = @as(u64, sym_index) << 32 | r_type,135 .pcrel => true,
131 .r_addend = lowered_relocs[0].off - 4,136 },
132 }, zo);137 },
133 } else if (emit.lower.bin_file.cast(.macho)) |macho_file| {138 .variable => |variable| .{
134 // Add relocation to the decl.139 .index = sym_index,
135 const zo = macho_file.getZigObject().?;140 .is_extern = false,
136 const atom = zo.symbols.items[emit.atom_index].getAtom(macho_file).?;141 .type = if (variable.is_threadlocal and comp.config.any_non_single_threaded) .tlv else .symbol,
137 try atom.addReloc(macho_file, .{142 },
138 .tag = .@"extern",143 else => .{ .index = sym_index, .is_extern = false, .type = .symbol },
139 .offset = end_offset - 4,144 },
140 .target = sym_index,145 };
141 .addend = lowered_relocs[0].off,146 },
142 .type = .branch,147 .uav => |uav| .{
143 .meta = .{148 .index = switch (try emit.bin_file.lowerUav(
144 .pcrel = true,149 emit.pt,
145 .has_subtractor = false,150 uav.val,
146 .length = 2,151 Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu),
147 .symbolnum = @intCast(sym_index),152 emit.lower.src_loc,
153 )) {
154 .mcv => |mcv| mcv.load_symbol,
155 .fail => |em| {
156 assert(emit.lower.err_msg == null);
157 emit.lower.err_msg = em;
158 return error.EmitFail;
159 },
148 },160 },
149 });161 .is_extern = false,
150 } else if (emit.lower.bin_file.cast(.coff)) |coff_file| {162 .type = .symbol,
151 // Add relocation to the decl.163 },
152 const atom_index = coff_file.getAtomIndexForSymbol(164 .lazy_sym => |lazy_sym| .{
153 .{ .sym_index = emit.atom_index, .file = null },165 .index = if (emit.bin_file.cast(.elf)) |elf_file|
154 ).?;166 elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, emit.pt, lazy_sym) catch |err|
155 const target = if (link.File.Coff.global_symbol_bit & sym_index != 0)167 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
156 coff_file.getGlobalByIndex(link.File.Coff.global_symbol_mask & sym_index)168 else if (emit.bin_file.cast(.macho)) |macho_file|
157 else169 macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err|
158 link.File.Coff.SymbolWithLoc{ .sym_index = sym_index, .file = null };170 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
159 try coff_file.addRelocation(atom_index, .{171 else if (emit.bin_file.cast(.coff)) |coff_file| sym_index: {
160 .type = .direct,172 const atom = coff_file.getOrCreateAtomForLazySymbol(emit.pt, lazy_sym) catch |err|
161 .target = target,173 return emit.fail("{s} creating lazy symbol", .{@errorName(err)});
162 .offset = end_offset - 4,174 break :sym_index coff_file.getAtom(atom).getSymbolIndex().?;
163 .addend = @intCast(lowered_relocs[0].off),175 } else if (emit.bin_file.cast(.plan9)) |p9_file|
164 .pcrel = true,176 p9_file.getOrCreateAtomForLazySymbol(emit.pt, lazy_sym) catch |err|
165 .length = 2,177 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
166 });
167 } else return emit.fail("TODO implement extern reloc for {s}", .{
168 @tagName(emit.lower.bin_file.tag),
169 }),
170 .linker_tlsld => |sym_index| {
171 const elf_file = emit.lower.bin_file.cast(.elf).?;
172 const zo = elf_file.zigObjectPtr().?;
173 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
174 const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD);
175 try atom.addReloc(gpa, .{
176 .r_offset = end_offset - 4,
177 .r_info = @as(u64, sym_index) << 32 | r_type,
178 .r_addend = lowered_relocs[0].off - 4,
179 }, zo);
180 },
181 .linker_dtpoff => |sym_index| {
182 const elf_file = emit.lower.bin_file.cast(.elf).?;
183 const zo = elf_file.zigObjectPtr().?;
184 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
185 const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32);
186 try atom.addReloc(gpa, .{
187 .r_offset = end_offset - 4,
188 .r_info = @as(u64, sym_index) << 32 | r_type,
189 .r_addend = lowered_relocs[0].off,
190 }, zo);
191 },
192 .linker_reloc, .linker_pcrel => |sym_index| if (emit.lower.bin_file.cast(.elf)) |elf_file| {
193 const zo = elf_file.zigObjectPtr().?;
194 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
195 const sym = zo.symbol(sym_index);
196 if (emit.lower.pic) {
197 const r_type: u32 = if (sym.flags.is_extern_ptr and lowered_relocs[0].target != .linker_pcrel)
198 @intFromEnum(std.elf.R_X86_64.GOTPCREL)
199 else178 else
200 @intFromEnum(std.elf.R_X86_64.PC32);179 return emit.fail("lazy symbols unimplemented for {s}", .{@tagName(emit.bin_file.tag)}),
201 try atom.addReloc(gpa, .{180 .is_extern = false,
202 .r_offset = end_offset - 4,181 .type = .symbol,
203 .r_info = @as(u64, sym_index) << 32 | r_type,182 },
204 .r_addend = lowered_relocs[0].off - 4,183 .extern_func => |extern_func| .{
205 }, zo);184 .index = if (emit.bin_file.cast(.elf)) |elf_file|
206 } else {185 try elf_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, null)
207 const r_type: u32 = if (sym.flags.is_tls)186 else if (emit.bin_file.cast(.macho)) |macho_file|
208 @intFromEnum(std.elf.R_X86_64.TPOFF32)187 try macho_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, null)
188 else if (emit.bin_file.cast(.coff)) |coff_file|
189 link.File.Coff.global_symbol_bit | try coff_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, null)
209 else190 else
210 @intFromEnum(std.elf.R_X86_64.@"32");191 return emit.fail("external symbols unimplemented for {s}", .{@tagName(emit.bin_file.tag)}),
211 try atom.addReloc(gpa, .{192 .is_extern = true,
212 .r_offset = end_offset - 4,193 .type = .symbol,
213 .r_info = @as(u64, sym_index) << 32 | r_type,194 },
214 .r_addend = lowered_relocs[0].off,195 },
215 }, zo);196 };
216 }197 const reloc_info = reloc_info_buf[0..reloc_info_index];
217 } else if (emit.lower.bin_file.cast(.macho)) |macho_file| {198 for (reloc_info) |*reloc| switch (reloc.target.type) {
218 const zo = macho_file.getZigObject().?;199 .inst, .table => {},
219 const atom = zo.symbols.items[emit.atom_index].getAtom(macho_file).?;200 .symbol => {
220 const sym = &zo.symbols.items[sym_index];201 switch (lowered_inst.encoding.mnemonic) {
221 const @"type": link.File.MachO.Relocation.Type = if (sym.flags.is_extern_ptr and lowered_relocs[0].target != .linker_pcrel)202 .call => {
222 .got_load203 reloc.target.type = .branch;
223 else if (sym.flags.tlv)204 if (emit.bin_file.cast(.coff)) |_| try emit.encodeInst(try .new(.none, .call, &.{
224 .tlv205 .{ .mem = .initRip(.ptr, 0) },
225 else206 }, emit.lower.target), reloc_info) else try emit.encodeInst(lowered_inst, reloc_info);
226 .signed;207 continue :lowered_inst;
227 try atom.addReloc(macho_file, .{
228 .tag = .@"extern",
229 .offset = @intCast(end_offset - 4),
230 .target = sym_index,
231 .addend = lowered_relocs[0].off,
232 .type = @"type",
233 .meta = .{
234 .pcrel = true,
235 .has_subtractor = false,
236 .length = 2,
237 .symbolnum = @intCast(sym_index),
238 },208 },
209 else => {},
210 }
211 if (emit.bin_file.cast(.elf)) |_| {
212 if (!emit.pic) switch (lowered_inst.encoding.mnemonic) {
213 .lea => try emit.encodeInst(try .new(.none, .mov, &.{
214 lowered_inst.ops[0],
215 .{ .imm = .s(0) },
216 }, emit.lower.target), reloc_info),
217 .mov => try emit.encodeInst(try .new(.none, .mov, &.{
218 lowered_inst.ops[0],
219 .{ .mem = .initSib(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, .{
220 .base = .{ .reg = .ds },
221 }) },
222 }, emit.lower.target), reloc_info),
223 else => unreachable,
224 } else if (reloc.target.is_extern) switch (lowered_inst.encoding.mnemonic) {
225 .lea => try emit.encodeInst(try .new(.none, .mov, &.{
226 lowered_inst.ops[0],
227 .{ .mem = .initRip(.ptr, 0) },
228 }, emit.lower.target), reloc_info),
229 .mov => {
230 try emit.encodeInst(try .new(.none, .mov, &.{
231 lowered_inst.ops[0],
232 .{ .mem = .initRip(.ptr, 0) },
233 }, emit.lower.target), reloc_info);
234 try emit.encodeInst(try .new(.none, .mov, &.{
235 lowered_inst.ops[0],
236 .{ .mem = .initSib(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, .{ .base = .{
237 .reg = lowered_inst.ops[0].reg.to64(),
238 } }) },
239 }, emit.lower.target), &.{});
240 },
241 else => unreachable,
242 } else switch (lowered_inst.encoding.mnemonic) {
243 .lea => try emit.encodeInst(try .new(.none, .lea, &.{
244 lowered_inst.ops[0],
245 .{ .mem = .initRip(.none, 0) },
246 }, emit.lower.target), reloc_info),
247 .mov => try emit.encodeInst(try .new(.none, .mov, &.{
248 lowered_inst.ops[0],
249 .{ .mem = .initRip(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, 0) },
250 }, emit.lower.target), reloc_info),
251 else => unreachable,
252 }
253 } else if (emit.bin_file.cast(.macho)) |_| {
254 if (reloc.target.is_extern) switch (lowered_inst.encoding.mnemonic) {
255 .lea => try emit.encodeInst(try .new(.none, .mov, &.{
256 lowered_inst.ops[0],
257 .{ .mem = .initRip(.ptr, 0) },
258 }, emit.lower.target), reloc_info),
259 .mov => {
260 try emit.encodeInst(try .new(.none, .mov, &.{
261 lowered_inst.ops[0],
262 .{ .mem = .initRip(.ptr, 0) },
263 }, emit.lower.target), reloc_info);
264 try emit.encodeInst(try .new(.none, .mov, &.{
265 lowered_inst.ops[0],
266 .{ .mem = .initSib(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, .{ .base = .{
267 .reg = lowered_inst.ops[0].reg.to64(),
268 } }) },
269 }, emit.lower.target), &.{});
270 },
271 else => unreachable,
272 } else switch (lowered_inst.encoding.mnemonic) {
273 .lea => try emit.encodeInst(try .new(.none, .lea, &.{
274 lowered_inst.ops[0],
275 .{ .mem = .initRip(.none, 0) },
276 }, emit.lower.target), reloc_info),
277 .mov => try emit.encodeInst(try .new(.none, .mov, &.{
278 lowered_inst.ops[0],
279 .{ .mem = .initRip(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, 0) },
280 }, emit.lower.target), reloc_info),
281 else => unreachable,
282 }
283 } else if (emit.bin_file.cast(.coff)) |_| {
284 if (reloc.target.is_extern) switch (lowered_inst.encoding.mnemonic) {
285 .lea => try emit.encodeInst(try .new(.none, .mov, &.{
286 lowered_inst.ops[0],
287 .{ .mem = .initRip(.ptr, 0) },
288 }, emit.lower.target), reloc_info),
289 .mov => {
290 const dst_reg = lowered_inst.ops[0].reg.to64();
291 try emit.encodeInst(try .new(.none, .mov, &.{
292 .{ .reg = dst_reg },
293 .{ .mem = .initRip(.ptr, 0) },
294 }, emit.lower.target), reloc_info);
295 try emit.encodeInst(try .new(.none, .mov, &.{
296 lowered_inst.ops[0],
297 .{ .mem = .initSib(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, .{ .base = .{
298 .reg = dst_reg,
299 } }) },
300 }, emit.lower.target), &.{});
301 },
302 else => unreachable,
303 } else switch (lowered_inst.encoding.mnemonic) {
304 .lea => try emit.encodeInst(try .new(.none, .lea, &.{
305 lowered_inst.ops[0],
306 .{ .mem = .initRip(.none, 0) },
307 }, emit.lower.target), reloc_info),
308 .mov => try emit.encodeInst(try .new(.none, .mov, &.{
309 lowered_inst.ops[0],
310 .{ .mem = .initRip(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, 0) },
311 }, emit.lower.target), reloc_info),
312 else => unreachable,
313 }
314 } else return emit.fail("TODO implement relocs for {s}", .{
315 @tagName(emit.bin_file.tag),
239 });316 });
240 } else unreachable,317 continue :lowered_inst;
241 .linker_got,318 },
242 .linker_direct,319 .branch, .tls => unreachable,
243 .linker_import,320 .tlv => {
244 => |sym_index| if (emit.lower.bin_file.cast(.elf)) |_| {321 if (emit.bin_file.cast(.elf)) |elf_file| {
245 unreachable;322 // TODO handle extern TLS vars, i.e., emit GD model
246 } else if (emit.lower.bin_file.cast(.macho)) |_| {323 if (emit.pic) switch (lowered_inst.encoding.mnemonic) {
247 unreachable;324 .lea, .mov => {
248 } else if (emit.lower.bin_file.cast(.coff)) |coff_file| {325 // Here, we currently assume local dynamic TLS vars, and so
249 const atom_index = coff_file.getAtomIndexForSymbol(.{326 // we emit LD model.
250 .sym_index = emit.atom_index,327 try emit.encodeInst(try .new(.none, .lea, &.{
251 .file = null,328 .{ .reg = .rdi },
252 }).?;329 .{ .mem = .initRip(.none, 0) },
253 const target = if (link.File.Coff.global_symbol_bit & sym_index != 0)330 }, emit.lower.target), &.{.{
254 coff_file.getGlobalByIndex(link.File.Coff.global_symbol_mask & sym_index)331 .op_index = 1,
255 else332 .target = .{
256 link.File.Coff.SymbolWithLoc{ .sym_index = sym_index, .file = null };333 .index = reloc.target.index,
257 try coff_file.addRelocation(atom_index, .{334 .is_extern = false,
258 .type = switch (lowered_relocs[0].target) {335 .type = .tls,
259 .linker_got => .got,336 },
260 .linker_direct => .direct,337 }});
261 .linker_import => .import,338 try emit.encodeInst(try .new(.none, .call, &.{
339 .{ .imm = .s(0) },
340 }, emit.lower.target), &.{.{
341 .op_index = 0,
342 .target = .{
343 .index = try elf_file.getGlobalSymbol("__tls_get_addr", null),
344 .is_extern = true,
345 .type = .branch,
346 },
347 }});
348 try emit.encodeInst(try .new(.none, lowered_inst.encoding.mnemonic, &.{
349 lowered_inst.ops[0],
350 .{ .mem = .initSib(.none, .{
351 .base = .{ .reg = .rax },
352 .disp = std.math.minInt(i32),
353 }) },
354 }, emit.lower.target), reloc_info);
355 },
356 else => unreachable,
357 } else switch (lowered_inst.encoding.mnemonic) {
358 .lea, .mov => {
359 // Since we are linking statically, we emit LE model directly.
360 try emit.encodeInst(try .new(.none, .mov, &.{
361 .{ .reg = .rax },
362 .{ .mem = .initSib(.qword, .{ .base = .{ .reg = .fs } }) },
363 }, emit.lower.target), &.{});
364 try emit.encodeInst(try .new(.none, lowered_inst.encoding.mnemonic, &.{
365 lowered_inst.ops[0],
366 .{ .mem = .initSib(.none, .{
367 .base = .{ .reg = .rax },
368 .disp = std.math.minInt(i32),
369 }) },
370 }, emit.lower.target), reloc_info);
371 },
262 else => unreachable,372 else => unreachable,
373 }
374 } else if (emit.bin_file.cast(.macho)) |_| switch (lowered_inst.encoding.mnemonic) {
375 .lea => {
376 try emit.encodeInst(try .new(.none, .mov, &.{
377 .{ .reg = .rdi },
378 .{ .mem = .initRip(.ptr, 0) },
379 }, emit.lower.target), reloc_info);
380 try emit.encodeInst(try .new(.none, .call, &.{
381 .{ .mem = .initSib(.qword, .{ .base = .{ .reg = .rdi } }) },
382 }, emit.lower.target), &.{});
383 try emit.encodeInst(try .new(.none, .mov, &.{
384 lowered_inst.ops[0],
385 .{ .reg = .rax },
386 }, emit.lower.target), &.{});
263 },387 },
264 .target = target,388 .mov => {
265 .offset = @intCast(end_offset - 4),389 try emit.encodeInst(try .new(.none, .mov, &.{
266 .addend = @intCast(lowered_relocs[0].off),390 .{ .reg = .rdi },
267 .pcrel = true,391 .{ .mem = .initRip(.ptr, 0) },
268 .length = 2,392 }, emit.lower.target), reloc_info);
269 });393 try emit.encodeInst(try .new(.none, .call, &.{
270 } else if (emit.lower.bin_file.cast(.plan9)) |p9_file| {394 .{ .mem = .initSib(.qword, .{ .base = .{ .reg = .rdi } }) },
271 try p9_file.addReloc(emit.atom_index, .{ // TODO we may need to add a .type field to the relocs if they are .linker_got instead of just .linker_direct395 }, emit.lower.target), &.{});
272 .target = sym_index, // we set sym_index to just be the atom index396 try emit.encodeInst(try .new(.none, .mov, &.{
273 .offset = @intCast(end_offset - 4),397 lowered_inst.ops[0],
274 .addend = @intCast(lowered_relocs[0].off),398 .{ .mem = .initSib(.qword, .{ .base = .{ .reg = .rax } }) },
275 .type = .pcrel,399 }, emit.lower.target), &.{});
400 },
401 else => unreachable,
402 } else return emit.fail("TODO implement relocs for {s}", .{
403 @tagName(emit.bin_file.tag),
276 });404 });
277 } else return emit.fail("TODO implement linker reloc for {s}", .{405 continue :lowered_inst;
278 @tagName(emit.lower.bin_file.tag),406 },
279 }),
280 };407 };
408 try emit.encodeInst(lowered_inst, reloc_info);
281 }409 }
282 std.debug.assert(lowered_relocs.len == 0);410 assert(lowered_relocs.len == 0);
283411
284 if (lowered.insts.len == 0) {412 if (lowered.insts.len == 0) {
285 const mir_inst = emit.lower.mir.instructions.get(mir_index);413 const mir_inst = emit.lower.mir.instructions.get(mir_index);
...@@ -338,7 +466,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -338,7 +466,7 @@ pub fn emitMir(emit: *Emit) Error!void {
338 log.debug("mirDbgEnterInline (line={d}, col={d})", .{466 log.debug("mirDbgEnterInline (line={d}, col={d})", .{
339 emit.prev_di_loc.line, emit.prev_di_loc.column,467 emit.prev_di_loc.line, emit.prev_di_loc.column,
340 });468 });
341 try dwarf.enterInlineFunc(mir_inst.data.func, emit.code.items.len, emit.prev_di_loc.line, emit.prev_di_loc.column);469 try dwarf.enterInlineFunc(mir_inst.data.ip_index, emit.code.items.len, emit.prev_di_loc.line, emit.prev_di_loc.column);
342 },470 },
343 .plan9 => {},471 .plan9 => {},
344 .none => {},472 .none => {},
...@@ -348,77 +476,49 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -348,77 +476,49 @@ pub fn emitMir(emit: *Emit) Error!void {
348 log.debug("mirDbgLeaveInline (line={d}, col={d})", .{476 log.debug("mirDbgLeaveInline (line={d}, col={d})", .{
349 emit.prev_di_loc.line, emit.prev_di_loc.column,477 emit.prev_di_loc.line, emit.prev_di_loc.column,
350 });478 });
351 try dwarf.leaveInlineFunc(mir_inst.data.func, emit.code.items.len);479 try dwarf.leaveInlineFunc(mir_inst.data.ip_index, emit.code.items.len);
352 },480 },
353 .plan9 => {},481 .plan9 => {},
354 .none => {},482 .none => {},
355 },483 },
356 .pseudo_dbg_local_a,484 .pseudo_dbg_arg_none,
357 .pseudo_dbg_local_ai_s,485 .pseudo_dbg_arg_i_s,
358 .pseudo_dbg_local_ai_u,486 .pseudo_dbg_arg_i_u,
359 .pseudo_dbg_local_ai_64,487 .pseudo_dbg_arg_i_64,
360 .pseudo_dbg_local_as,488 .pseudo_dbg_arg_ro,
361 .pseudo_dbg_local_aso,489 .pseudo_dbg_arg_fa,
362 .pseudo_dbg_local_aro,490 .pseudo_dbg_arg_m,
363 .pseudo_dbg_local_af,491 .pseudo_dbg_var_none,
364 .pseudo_dbg_local_am,492 .pseudo_dbg_var_i_s,
493 .pseudo_dbg_var_i_u,
494 .pseudo_dbg_var_i_64,
495 .pseudo_dbg_var_ro,
496 .pseudo_dbg_var_fa,
497 .pseudo_dbg_var_m,
365 => switch (emit.debug_output) {498 => switch (emit.debug_output) {
366 .dwarf => |dwarf| {499 .dwarf => |dwarf| {
367 var loc_buf: [2]link.File.Dwarf.Loc = undefined;500 var loc_buf: [2]link.File.Dwarf.Loc = undefined;
368 const air_inst_index, const loc: link.File.Dwarf.Loc = switch (mir_inst.ops) {501 const loc: link.File.Dwarf.Loc = loc: switch (mir_inst.ops) {
369 else => unreachable,502 else => unreachable,
370 .pseudo_dbg_local_a => .{ mir_inst.data.a.air_inst, .empty },503 .pseudo_dbg_arg_none, .pseudo_dbg_var_none => .empty,
371 .pseudo_dbg_local_ai_s,504 .pseudo_dbg_arg_i_s,
372 .pseudo_dbg_local_ai_u,505 .pseudo_dbg_arg_i_u,
373 .pseudo_dbg_local_ai_64,506 .pseudo_dbg_var_i_s,
374 => .{ mir_inst.data.ai.air_inst, .{ .stack_value = stack_value: {507 .pseudo_dbg_var_i_u,
375 loc_buf[0] = switch (emit.lower.imm(mir_inst.ops, mir_inst.data.ai.i)) {508 => .{ .stack_value = stack_value: {
509 loc_buf[0] = switch (emit.lower.imm(mir_inst.ops, mir_inst.data.i.i)) {
376 .signed => |s| .{ .consts = s },510 .signed => |s| .{ .consts = s },
377 .unsigned => |u| .{ .constu = u },511 .unsigned => |u| .{ .constu = u },
378 };512 };
379 break :stack_value &loc_buf[0];513 break :stack_value &loc_buf[0];
380 } } },
381 .pseudo_dbg_local_as => .{ mir_inst.data.as.air_inst, .{
382 .addr_reloc = mir_inst.data.as.sym_index,
383 } },514 } },
384 .pseudo_dbg_local_aso => loc: {515 .pseudo_dbg_arg_i_64, .pseudo_dbg_var_i_64 => .{ .stack_value = stack_value: {
385 const sym_off = emit.lower.mir.extraData(516 loc_buf[0] = .{ .constu = mir_inst.data.i64 };
386 bits.SymbolOffset,517 break :stack_value &loc_buf[0];
387 mir_inst.data.ax.payload,518 } },
388 ).data;519 .pseudo_dbg_arg_fa, .pseudo_dbg_var_fa => {
389 break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{520 const reg_off = emit.lower.mir.resolveFrameAddr(mir_inst.data.fa);
390 sym: {521 break :loc .{ .plus = .{
391 loc_buf[0] = .{ .addr_reloc = sym_off.sym_index };
392 break :sym &loc_buf[0];
393 },
394 off: {
395 loc_buf[1] = .{ .consts = sym_off.off };
396 break :off &loc_buf[1];
397 },
398 } } };
399 },
400 .pseudo_dbg_local_aro => loc: {
401 const air_off = emit.lower.mir.extraData(
402 Mir.AirOffset,
403 mir_inst.data.rx.payload,
404 ).data;
405 break :loc .{ air_off.air_inst, .{ .plus = .{
406 reg: {
407 loc_buf[0] = .{ .breg = mir_inst.data.rx.r1.dwarfNum() };
408 break :reg &loc_buf[0];
409 },
410 off: {
411 loc_buf[1] = .{ .consts = air_off.off };
412 break :off &loc_buf[1];
413 },
414 } } };
415 },
416 .pseudo_dbg_local_af => loc: {
417 const reg_off = emit.lower.mir.resolveFrameAddr(emit.lower.mir.extraData(
418 bits.FrameAddr,
419 mir_inst.data.ax.payload,
420 ).data);
421 break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
422 reg: {522 reg: {
423 loc_buf[0] = .{ .breg = reg_off.reg.dwarfNum() };523 loc_buf[0] = .{ .breg = reg_off.reg.dwarfNum() };
424 break :reg &loc_buf[0];524 break :reg &loc_buf[0];
...@@ -427,18 +527,54 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -427,18 +527,54 @@ pub fn emitMir(emit: *Emit) Error!void {
427 loc_buf[1] = .{ .consts = reg_off.off };527 loc_buf[1] = .{ .consts = reg_off.off };
428 break :off &loc_buf[1];528 break :off &loc_buf[1];
429 },529 },
430 } } };530 } };
431 },531 },
432 .pseudo_dbg_local_am => loc: {532 .pseudo_dbg_arg_m, .pseudo_dbg_var_m => {
433 const mem = emit.lower.mem(undefined, mir_inst.data.ax.payload);533 const mem = emit.lower.mir.resolveMemoryExtra(mir_inst.data.x.payload).decode();
434 break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{534 break :loc .{ .plus = .{
435 base: {535 base: {
436 loc_buf[0] = switch (mem.base()) {536 loc_buf[0] = switch (mem.base()) {
437 .none => .{ .constu = 0 },537 .none => .{ .constu = 0 },
438 .reg => |reg| .{ .breg = reg.dwarfNum() },538 .reg => |reg| .{ .breg = reg.dwarfNum() },
439 .frame, .table, .rip_inst => unreachable,539 .frame, .table, .rip_inst => unreachable,
440 .reloc => |sym_index| .{ .addr_reloc = sym_index },540 .nav => |nav| .{ .addr_reloc = switch (codegen.genNavRef(
441 .pcrel => unreachable,541 emit.bin_file,
542 emit.pt,
543 emit.lower.src_loc,
544 nav,
545 emit.lower.target.*,
546 ) catch |err| switch (err) {
547 error.CodegenFail,
548 => return emit.fail("unable to codegen: {s}", .{@errorName(err)}),
549 else => |e| return e,
550 }) {
551 .mcv => |mcv| switch (mcv) {
552 else => unreachable,
553 .load_direct, .load_symbol => |sym_index| sym_index,
554 },
555 .fail => |em| {
556 assert(emit.lower.err_msg == null);
557 emit.lower.err_msg = em;
558 return error.EmitFail;
559 },
560 } },
561 .uav => |uav| .{ .addr_reloc = switch (try emit.bin_file.lowerUav(
562 emit.pt,
563 uav.val,
564 Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu),
565 emit.lower.src_loc,
566 )) {
567 .mcv => |mcv| switch (mcv) {
568 else => unreachable,
569 .load_direct, .load_symbol => |sym_index| sym_index,
570 },
571 .fail => |em| {
572 assert(emit.lower.err_msg == null);
573 emit.lower.err_msg = em;
574 return error.EmitFail;
575 },
576 } },
577 .lazy_sym, .extern_func => unreachable,
442 };578 };
443 break :base &loc_buf[0];579 break :base &loc_buf[0];
444 },580 },
...@@ -449,34 +585,57 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -449,34 +585,57 @@ pub fn emitMir(emit: *Emit) Error!void {
449 };585 };
450 break :disp &loc_buf[1];586 break :disp &loc_buf[1];
451 },587 },
452 } } };588 } };
453 },589 },
454 };590 };
455 const ip = &emit.lower.bin_file.comp.zcu.?.intern_pool;591
456 const air_inst = emit.air.instructions.get(@intFromEnum(air_inst_index));592 const local = &emit.lower.mir.locals[local_index];
457 const name: Air.NullTerminatedString = switch (air_inst.tag) {593 local_index += 1;
458 else => unreachable,594 try dwarf.genLocalVarDebugInfo(
459 .arg => air_inst.data.arg.name,595 switch (mir_inst.ops) {
460 .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => @enumFromInt(air_inst.data.pl_op.payload),
461 };
462 try dwarf.genLocalDebugInfo(
463 switch (air_inst.tag) {
464 else => unreachable,596 else => unreachable,
465 .arg, .dbg_arg_inline => .local_arg,597 .pseudo_dbg_arg_none,
466 .dbg_var_ptr, .dbg_var_val => .local_var,598 .pseudo_dbg_arg_i_s,
599 .pseudo_dbg_arg_i_u,
600 .pseudo_dbg_arg_i_64,
601 .pseudo_dbg_arg_ro,
602 .pseudo_dbg_arg_fa,
603 .pseudo_dbg_arg_m,
604 .pseudo_dbg_arg_val,
605 => .arg,
606 .pseudo_dbg_var_none,
607 .pseudo_dbg_var_i_s,
608 .pseudo_dbg_var_i_u,
609 .pseudo_dbg_var_i_64,
610 .pseudo_dbg_var_ro,
611 .pseudo_dbg_var_fa,
612 .pseudo_dbg_var_m,
613 .pseudo_dbg_var_val,
614 => .local_var,
467 },615 },
468 name.toSlice(emit.air),616 local.name.toSlice(&emit.lower.mir),
469 switch (air_inst.tag) {617 .fromInterned(local.type),
618 loc,
619 );
620 },
621 .plan9, .none => local_index += 1,
622 },
623 .pseudo_dbg_arg_val, .pseudo_dbg_var_val => switch (emit.debug_output) {
624 .dwarf => |dwarf| {
625 const local = &emit.lower.mir.locals[local_index];
626 local_index += 1;
627 try dwarf.genLocalConstDebugInfo(
628 emit.lower.src_loc,
629 switch (mir_inst.ops) {
470 else => unreachable,630 else => unreachable,
471 .arg => emit.air.typeOfIndex(air_inst_index, ip),631 .pseudo_dbg_arg_val => .comptime_arg,
472 .dbg_var_ptr => emit.air.typeOf(air_inst.data.pl_op.operand, ip).childTypeIp(ip),632 .pseudo_dbg_var_val => .local_const,
473 .dbg_var_val, .dbg_arg_inline => emit.air.typeOf(air_inst.data.pl_op.operand, ip),
474 },633 },
475 loc,634 local.name.toSlice(&emit.lower.mir),
635 .fromInterned(mir_inst.data.ip_index),
476 );636 );
477 },637 },
478 .plan9 => {},638 .plan9, .none => local_index += 1,
479 .none => {},
480 },639 },
481 .pseudo_dbg_var_args_none => switch (emit.debug_output) {640 .pseudo_dbg_var_args_none => switch (emit.debug_output) {
482 .dwarf => |dwarf| try dwarf.genVarArgsDebugInfo(),641 .dwarf => |dwarf| try dwarf.genVarArgsDebugInfo(),
...@@ -488,8 +647,8 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -488,8 +647,8 @@ pub fn emitMir(emit: *Emit) Error!void {
488 }647 }
489 }648 }
490 }649 }
491 for (relocs.items) |reloc| {650 for (emit.relocs.items) |reloc| {
492 const target = code_offset_mapping[reloc.target];651 const target = emit.code_offset_mapping.items[reloc.target];
493 const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.inst_offset + reloc.inst_length)) + reloc.target_offset;652 const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.inst_offset + reloc.inst_length)) + reloc.target_offset;
494 const inst_bytes = emit.code.items[reloc.inst_offset..][0..reloc.inst_length];653 const inst_bytes = emit.code.items[reloc.inst_offset..][0..reloc.inst_length];
495 switch (reloc.source_length) {654 switch (reloc.source_length) {
...@@ -503,13 +662,13 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -503,13 +662,13 @@ pub fn emitMir(emit: *Emit) Error!void {
503 }662 }
504 }663 }
505 if (emit.lower.mir.table.len > 0) {664 if (emit.lower.mir.table.len > 0) {
506 if (emit.lower.bin_file.cast(.elf)) |elf_file| {665 if (emit.bin_file.cast(.elf)) |elf_file| {
507 const zo = elf_file.zigObjectPtr().?;666 const zo = elf_file.zigObjectPtr().?;
508 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;667 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
509668
510 const ptr_size = @divExact(emit.lower.target.ptrBitWidth(), 8);669 const ptr_size = @divExact(emit.lower.target.ptrBitWidth(), 8);
511 var table_offset = std.mem.alignForward(u32, @intCast(emit.code.items.len), ptr_size);670 var table_offset = std.mem.alignForward(u32, @intCast(emit.code.items.len), ptr_size);
512 for (table_relocs.items) |table_reloc| try atom.addReloc(gpa, .{671 for (emit.table_relocs.items) |table_reloc| try atom.addReloc(gpa, .{
513 .r_offset = table_reloc.source_offset,672 .r_offset = table_reloc.source_offset,
514 .r_info = @as(u64, emit.atom_index) << 32 | @intFromEnum(std.elf.R_X86_64.@"32"),673 .r_info = @as(u64, emit.atom_index) << 32 | @intFromEnum(std.elf.R_X86_64.@"32"),
515 .r_addend = @as(i64, table_offset) + table_reloc.target_offset,674 .r_addend = @as(i64, table_offset) + table_reloc.target_offset,
...@@ -518,7 +677,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -518,7 +677,7 @@ pub fn emitMir(emit: *Emit) Error!void {
518 try atom.addReloc(gpa, .{677 try atom.addReloc(gpa, .{
519 .r_offset = table_offset,678 .r_offset = table_offset,
520 .r_info = @as(u64, emit.atom_index) << 32 | @intFromEnum(std.elf.R_X86_64.@"64"),679 .r_info = @as(u64, emit.atom_index) << 32 | @intFromEnum(std.elf.R_X86_64.@"64"),
521 .r_addend = code_offset_mapping[entry],680 .r_addend = emit.code_offset_mapping.items[entry],
522 }, zo);681 }, zo);
523 table_offset += ptr_size;682 table_offset += ptr_size;
524 }683 }
...@@ -527,6 +686,200 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -527,6 +686,200 @@ pub fn emitMir(emit: *Emit) Error!void {
527 }686 }
528}687}
529688
689pub fn deinit(emit: *Emit) void {
690 const gpa = emit.bin_file.comp.gpa;
691 emit.code_offset_mapping.deinit(gpa);
692 emit.relocs.deinit(gpa);
693 emit.table_relocs.deinit(gpa);
694 emit.* = undefined;
695}
696
697const RelocInfo = struct {
698 op_index: Lower.InstOpIndex,
699 off: i32 = 0,
700 target: Target,
701
702 const Target = struct {
703 index: u32,
704 is_extern: bool,
705 type: Target.Type,
706 force_pcrel_direct: bool = false,
707
708 const Type = enum { inst, table, symbol, branch, tls, tlv };
709 };
710};
711
712fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocInfo) Error!void {
713 const comp = emit.bin_file.comp;
714 const gpa = comp.gpa;
715 const start_offset: u32 = @intCast(emit.code.items.len);
716 try lowered_inst.encode(emit.code.writer(gpa), .{});
717 const end_offset: u32 = @intCast(emit.code.items.len);
718 for (reloc_info) |reloc| switch (reloc.target.type) {
719 .inst => {
720 const inst_length: u4 = @intCast(end_offset - start_offset);
721 const reloc_offset, const reloc_length = reloc_offset_length: {
722 var reloc_offset = inst_length;
723 var op_index: usize = lowered_inst.ops.len;
724 while (true) {
725 op_index -= 1;
726 const op = lowered_inst.encoding.data.ops[op_index];
727 if (op == .none) continue;
728 const is_mem = op.isMemory();
729 const enc_length: u4 = if (is_mem) switch (lowered_inst.ops[op_index].mem.sib.base) {
730 .rip_inst => 4,
731 else => unreachable,
732 } else @intCast(std.math.divCeil(u7, @intCast(op.immBitSize()), 8) catch unreachable);
733 reloc_offset -= enc_length;
734 if (op_index == reloc.op_index) break :reloc_offset_length .{ reloc_offset, enc_length };
735 assert(!is_mem);
736 }
737 };
738 try emit.relocs.append(emit.lower.allocator, .{
739 .inst_offset = start_offset,
740 .inst_length = inst_length,
741 .source_offset = reloc_offset,
742 .source_length = reloc_length,
743 .target = reloc.target.index,
744 .target_offset = reloc.off,
745 });
746 },
747 .table => try emit.table_relocs.append(emit.lower.allocator, .{
748 .source_offset = end_offset - 4,
749 .target_offset = reloc.off,
750 }),
751 .symbol => if (emit.bin_file.cast(.elf)) |elf_file| {
752 const zo = elf_file.zigObjectPtr().?;
753 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
754 const r_type: std.elf.R_X86_64 = if (!emit.pic)
755 .@"32"
756 else if (reloc.target.is_extern and !reloc.target.force_pcrel_direct)
757 .GOTPCREL
758 else
759 .PC32;
760 try atom.addReloc(gpa, .{
761 .r_offset = end_offset - 4,
762 .r_info = @as(u64, reloc.target.index) << 32 | @intFromEnum(r_type),
763 .r_addend = if (emit.pic) reloc.off - 4 else reloc.off,
764 }, zo);
765 } else if (emit.bin_file.cast(.macho)) |macho_file| {
766 const zo = macho_file.getZigObject().?;
767 const atom = zo.symbols.items[emit.atom_index].getAtom(macho_file).?;
768 try atom.addReloc(macho_file, .{
769 .tag = .@"extern",
770 .offset = end_offset - 4,
771 .target = reloc.target.index,
772 .addend = reloc.off,
773 .type = if (reloc.target.is_extern and !reloc.target.force_pcrel_direct) .got_load else .signed,
774 .meta = .{
775 .pcrel = true,
776 .has_subtractor = false,
777 .length = 2,
778 .symbolnum = @intCast(reloc.target.index),
779 },
780 });
781 } else if (emit.bin_file.cast(.coff)) |coff_file| {
782 const atom_index = coff_file.getAtomIndexForSymbol(
783 .{ .sym_index = emit.atom_index, .file = null },
784 ).?;
785 try coff_file.addRelocation(atom_index, .{
786 .type = if (reloc.target.is_extern) .got else .direct,
787 .target = if (reloc.target.is_extern)
788 coff_file.getGlobalByIndex(reloc.target.index)
789 else
790 .{ .sym_index = reloc.target.index, .file = null },
791 .offset = end_offset - 4,
792 .addend = @intCast(reloc.off),
793 .pcrel = true,
794 .length = 2,
795 });
796 } else unreachable,
797 .branch => if (emit.bin_file.cast(.elf)) |elf_file| {
798 const zo = elf_file.zigObjectPtr().?;
799 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
800 const r_type: std.elf.R_X86_64 = .PLT32;
801 try atom.addReloc(gpa, .{
802 .r_offset = end_offset - 4,
803 .r_info = @as(u64, reloc.target.index) << 32 | @intFromEnum(r_type),
804 .r_addend = reloc.off - 4,
805 }, zo);
806 } else if (emit.bin_file.cast(.macho)) |macho_file| {
807 const zo = macho_file.getZigObject().?;
808 const atom = zo.symbols.items[emit.atom_index].getAtom(macho_file).?;
809 try atom.addReloc(macho_file, .{
810 .tag = .@"extern",
811 .offset = end_offset - 4,
812 .target = reloc.target.index,
813 .addend = reloc.off,
814 .type = .branch,
815 .meta = .{
816 .pcrel = true,
817 .has_subtractor = false,
818 .length = 2,
819 .symbolnum = @intCast(reloc.target.index),
820 },
821 });
822 } else if (emit.bin_file.cast(.coff)) |coff_file| {
823 const atom_index = coff_file.getAtomIndexForSymbol(
824 .{ .sym_index = emit.atom_index, .file = null },
825 ).?;
826 try coff_file.addRelocation(atom_index, .{
827 .type = if (reloc.target.is_extern) .import else .got,
828 .target = if (reloc.target.is_extern)
829 coff_file.getGlobalByIndex(reloc.target.index)
830 else
831 .{ .sym_index = reloc.target.index, .file = null },
832 .offset = end_offset - 4,
833 .addend = @intCast(reloc.off),
834 .pcrel = true,
835 .length = 2,
836 });
837 } else return emit.fail("TODO implement {s} reloc for {s}", .{
838 @tagName(reloc.target.type), @tagName(emit.bin_file.tag),
839 }),
840 .tls => if (emit.bin_file.cast(.elf)) |elf_file| {
841 const zo = elf_file.zigObjectPtr().?;
842 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
843 const r_type: std.elf.R_X86_64 = if (emit.pic) .TLSLD else unreachable;
844 try atom.addReloc(gpa, .{
845 .r_offset = end_offset - 4,
846 .r_info = @as(u64, reloc.target.index) << 32 | @intFromEnum(r_type),
847 .r_addend = reloc.off - 4,
848 }, zo);
849 } else return emit.fail("TODO implement {s} reloc for {s}", .{
850 @tagName(reloc.target.type), @tagName(emit.bin_file.tag),
851 }),
852 .tlv => if (emit.bin_file.cast(.elf)) |elf_file| {
853 const zo = elf_file.zigObjectPtr().?;
854 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
855 const r_type: std.elf.R_X86_64 = if (emit.pic) .DTPOFF32 else .TPOFF32;
856 try atom.addReloc(gpa, .{
857 .r_offset = end_offset - 4,
858 .r_info = @as(u64, reloc.target.index) << 32 | @intFromEnum(r_type),
859 .r_addend = reloc.off,
860 }, zo);
861 } else if (emit.bin_file.cast(.macho)) |macho_file| {
862 const zo = macho_file.getZigObject().?;
863 const atom = zo.symbols.items[emit.atom_index].getAtom(macho_file).?;
864 try atom.addReloc(macho_file, .{
865 .tag = .@"extern",
866 .offset = end_offset - 4,
867 .target = reloc.target.index,
868 .addend = reloc.off,
869 .type = .tlv,
870 .meta = .{
871 .pcrel = true,
872 .has_subtractor = false,
873 .length = 2,
874 .symbolnum = @intCast(reloc.target.index),
875 },
876 });
877 } else return emit.fail("TODO implement {s} reloc for {s}", .{
878 @tagName(reloc.target.type), @tagName(emit.bin_file.tag),
879 }),
880 };
881}
882
530fn fail(emit: *Emit, comptime format: []const u8, args: anytype) Error {883fn fail(emit: *Emit, comptime format: []const u8, args: anytype) Error {
531 return switch (emit.lower.fail(format, args)) {884 return switch (emit.lower.fail(format, args)) {
532 error.LowerFail => error.EmitFail,885 error.LowerFail => error.EmitFail,
...@@ -610,12 +963,17 @@ fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void {...@@ -610,12 +963,17 @@ fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void {
610 }963 }
611}964}
612965
966const assert = std.debug.assert;
613const bits = @import("bits.zig");967const bits = @import("bits.zig");
968const codegen = @import("../../codegen.zig");
969const Emit = @This();
970const encoder = @import("encoder.zig");
971const Instruction = encoder.Instruction;
972const InternPool = @import("../../InternPool.zig");
614const link = @import("../../link.zig");973const link = @import("../../link.zig");
615const log = std.log.scoped(.emit);974const log = std.log.scoped(.emit);
616const std = @import("std");
617
618const Air = @import("../../Air.zig");
619const Emit = @This();
620const Lower = @import("Lower.zig");975const Lower = @import("Lower.zig");
621const Mir = @import("Mir.zig");976const Mir = @import("Mir.zig");
977const std = @import("std");
978const Type = @import("../../Type.zig");
979const Zcu = @import("../../Zcu.zig");
src/arch/x86_64/Lower.zig+147-279
...@@ -1,10 +1,6 @@...@@ -1,10 +1,6 @@
1//! This file contains the functionality for lowering x86_64 MIR to Instructions1//! This file contains the functionality for lowering x86_64 MIR to Instructions
22
3bin_file: *link.File,
4target: *const std.Target,3target: *const std.Target,
5output_mode: std.builtin.OutputMode,
6link_mode: std.builtin.LinkMode,
7pic: bool,
8allocator: std.mem.Allocator,4allocator: std.mem.Allocator,
9mir: Mir,5mir: Mir,
10cc: std.builtin.CallingConvention,6cc: std.builtin.CallingConvention,
...@@ -17,7 +13,6 @@ result_relocs: [max_result_relocs]Reloc = undefined,...@@ -17,7 +13,6 @@ result_relocs: [max_result_relocs]Reloc = undefined,
1713
18const max_result_insts = @max(14const max_result_insts = @max(
19 1, // non-pseudo instructions15 1, // non-pseudo instructions
20 3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode
21 2, // cmovcc: cmovcc \ cmovcc16 2, // cmovcc: cmovcc \ cmovcc
22 3, // setcc: setcc \ setcc \ logicop17 3, // setcc: setcc \ setcc \ logicop
23 2, // jcc: jcc \ jcc18 2, // jcc: jcc \ jcc
...@@ -25,6 +20,7 @@ const max_result_insts = @max(...@@ -25,6 +20,7 @@ const max_result_insts = @max(
25 pseudo_probe_adjust_unrolled_max_insts,20 pseudo_probe_adjust_unrolled_max_insts,
26 pseudo_probe_adjust_setup_insts,21 pseudo_probe_adjust_setup_insts,
27 pseudo_probe_adjust_loop_insts,22 pseudo_probe_adjust_loop_insts,
23 abi.zigcc.callee_preserved_regs.len * 2, // push_regs/pop_regs
28 abi.Win64.callee_preserved_regs.len * 2, // push_regs/pop_regs24 abi.Win64.callee_preserved_regs.len * 2, // push_regs/pop_regs
29 abi.SysV.callee_preserved_regs.len * 2, // push_regs/pop_regs25 abi.SysV.callee_preserved_regs.len * 2, // push_regs/pop_regs
30);26);
...@@ -33,14 +29,13 @@ const max_result_relocs = @max(...@@ -33,14 +29,13 @@ const max_result_relocs = @max(
33 2, // jcc: jcc \ jcc29 2, // jcc: jcc \ jcc
34 2, // test \ jcc \ probe \ sub \ jmp30 2, // test \ jcc \ probe \ sub \ jmp
35 1, // probe \ sub \ jcc31 1, // probe \ sub \ jcc
36 3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode
37);32);
3833
39const ResultInstIndex = std.math.IntFittingRange(0, max_result_insts - 1);34const ResultInstIndex = std.math.IntFittingRange(0, max_result_insts);
40const ResultRelocIndex = std.math.IntFittingRange(0, max_result_relocs - 1);35const ResultRelocIndex = std.math.IntFittingRange(0, max_result_relocs);
41const InstOpIndex = std.math.IntFittingRange(36pub const InstOpIndex = std.math.IntFittingRange(
42 0,37 0,
43 @typeInfo(@FieldType(Instruction, "ops")).array.len - 1,38 @typeInfo(@FieldType(Instruction, "ops")).array.len,
44);39);
4540
46pub const pseudo_probe_align_insts = 5; // test \ jcc \ probe \ sub \ jmp41pub const pseudo_probe_align_insts = 5; // test \ jcc \ probe \ sub \ jmp
...@@ -54,7 +49,8 @@ pub const Error = error{...@@ -54,7 +49,8 @@ pub const Error = error{
54 LowerFail,49 LowerFail,
55 InvalidInstruction,50 InvalidInstruction,
56 CannotEncode,51 CannotEncode,
57};52 CodegenFail,
53} || codegen.GenerateSymbolError;
5854
59pub const Reloc = struct {55pub const Reloc = struct {
60 lowered_inst_index: ResultInstIndex,56 lowered_inst_index: ResultInstIndex,
...@@ -65,14 +61,10 @@ pub const Reloc = struct {...@@ -65,14 +61,10 @@ pub const Reloc = struct {
65 const Target = union(enum) {61 const Target = union(enum) {
66 inst: Mir.Inst.Index,62 inst: Mir.Inst.Index,
67 table,63 table,
68 linker_reloc: u32,64 nav: InternPool.Nav.Index,
69 linker_pcrel: u32,65 uav: InternPool.Key.Ptr.BaseAddr.Uav,
70 linker_tlsld: u32,66 lazy_sym: link.File.LazySymbol,
71 linker_dtpoff: u32,67 extern_func: Mir.NullTerminatedString,
72 linker_extern_fn: u32,
73 linker_got: u32,
74 linker_direct: u32,
75 linker_import: u32,
76 };68 };
77};69};
7870
...@@ -80,7 +72,7 @@ const Options = struct { allow_frame_locs: bool };...@@ -80,7 +72,7 @@ const Options = struct { allow_frame_locs: bool };
8072
81/// The returned slice is overwritten by the next call to lowerMir.73/// The returned slice is overwritten by the next call to lowerMir.
82pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {74pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
83 insts: []const Instruction,75 insts: []Instruction,
84 relocs: []const Reloc,76 relocs: []const Reloc,
85} {77} {
86 lower.result_insts = undefined;78 lower.result_insts = undefined;
...@@ -98,130 +90,130 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -98,130 +90,130 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
98 .pseudo => switch (inst.ops) {90 .pseudo => switch (inst.ops) {
99 .pseudo_cmov_z_and_np_rr => {91 .pseudo_cmov_z_and_np_rr => {
100 assert(inst.data.rr.fixes == ._);92 assert(inst.data.rr.fixes == ._);
101 try lower.emit(.none, .cmovnz, &.{93 try lower.encode(.none, .cmovnz, &.{
102 .{ .reg = inst.data.rr.r2 },94 .{ .reg = inst.data.rr.r2 },
103 .{ .reg = inst.data.rr.r1 },95 .{ .reg = inst.data.rr.r1 },
104 });96 });
105 try lower.emit(.none, .cmovnp, &.{97 try lower.encode(.none, .cmovnp, &.{
106 .{ .reg = inst.data.rr.r1 },98 .{ .reg = inst.data.rr.r1 },
107 .{ .reg = inst.data.rr.r2 },99 .{ .reg = inst.data.rr.r2 },
108 });100 });
109 },101 },
110 .pseudo_cmov_nz_or_p_rr => {102 .pseudo_cmov_nz_or_p_rr => {
111 assert(inst.data.rr.fixes == ._);103 assert(inst.data.rr.fixes == ._);
112 try lower.emit(.none, .cmovnz, &.{104 try lower.encode(.none, .cmovnz, &.{
113 .{ .reg = inst.data.rr.r1 },105 .{ .reg = inst.data.rr.r1 },
114 .{ .reg = inst.data.rr.r2 },106 .{ .reg = inst.data.rr.r2 },
115 });107 });
116 try lower.emit(.none, .cmovp, &.{108 try lower.encode(.none, .cmovp, &.{
117 .{ .reg = inst.data.rr.r1 },109 .{ .reg = inst.data.rr.r1 },
118 .{ .reg = inst.data.rr.r2 },110 .{ .reg = inst.data.rr.r2 },
119 });111 });
120 },112 },
121 .pseudo_cmov_nz_or_p_rm => {113 .pseudo_cmov_nz_or_p_rm => {
122 assert(inst.data.rx.fixes == ._);114 assert(inst.data.rx.fixes == ._);
123 try lower.emit(.none, .cmovnz, &.{115 try lower.encode(.none, .cmovnz, &.{
124 .{ .reg = inst.data.rx.r1 },116 .{ .reg = inst.data.rx.r1 },
125 .{ .mem = lower.mem(1, inst.data.rx.payload) },117 .{ .mem = lower.mem(1, inst.data.rx.payload) },
126 });118 });
127 try lower.emit(.none, .cmovp, &.{119 try lower.encode(.none, .cmovp, &.{
128 .{ .reg = inst.data.rx.r1 },120 .{ .reg = inst.data.rx.r1 },
129 .{ .mem = lower.mem(1, inst.data.rx.payload) },121 .{ .mem = lower.mem(1, inst.data.rx.payload) },
130 });122 });
131 },123 },
132 .pseudo_set_z_and_np_r => {124 .pseudo_set_z_and_np_r => {
133 assert(inst.data.rr.fixes == ._);125 assert(inst.data.rr.fixes == ._);
134 try lower.emit(.none, .setz, &.{126 try lower.encode(.none, .setz, &.{
135 .{ .reg = inst.data.rr.r1 },127 .{ .reg = inst.data.rr.r1 },
136 });128 });
137 try lower.emit(.none, .setnp, &.{129 try lower.encode(.none, .setnp, &.{
138 .{ .reg = inst.data.rr.r2 },130 .{ .reg = inst.data.rr.r2 },
139 });131 });
140 try lower.emit(.none, .@"and", &.{132 try lower.encode(.none, .@"and", &.{
141 .{ .reg = inst.data.rr.r1 },133 .{ .reg = inst.data.rr.r1 },
142 .{ .reg = inst.data.rr.r2 },134 .{ .reg = inst.data.rr.r2 },
143 });135 });
144 },136 },
145 .pseudo_set_z_and_np_m => {137 .pseudo_set_z_and_np_m => {
146 assert(inst.data.rx.fixes == ._);138 assert(inst.data.rx.fixes == ._);
147 try lower.emit(.none, .setz, &.{139 try lower.encode(.none, .setz, &.{
148 .{ .mem = lower.mem(0, inst.data.rx.payload) },140 .{ .mem = lower.mem(0, inst.data.rx.payload) },
149 });141 });
150 try lower.emit(.none, .setnp, &.{142 try lower.encode(.none, .setnp, &.{
151 .{ .reg = inst.data.rx.r1 },143 .{ .reg = inst.data.rx.r1 },
152 });144 });
153 try lower.emit(.none, .@"and", &.{145 try lower.encode(.none, .@"and", &.{
154 .{ .mem = lower.mem(0, inst.data.rx.payload) },146 .{ .mem = lower.mem(0, inst.data.rx.payload) },
155 .{ .reg = inst.data.rx.r1 },147 .{ .reg = inst.data.rx.r1 },
156 });148 });
157 },149 },
158 .pseudo_set_nz_or_p_r => {150 .pseudo_set_nz_or_p_r => {
159 assert(inst.data.rr.fixes == ._);151 assert(inst.data.rr.fixes == ._);
160 try lower.emit(.none, .setnz, &.{152 try lower.encode(.none, .setnz, &.{
161 .{ .reg = inst.data.rr.r1 },153 .{ .reg = inst.data.rr.r1 },
162 });154 });
163 try lower.emit(.none, .setp, &.{155 try lower.encode(.none, .setp, &.{
164 .{ .reg = inst.data.rr.r2 },156 .{ .reg = inst.data.rr.r2 },
165 });157 });
166 try lower.emit(.none, .@"or", &.{158 try lower.encode(.none, .@"or", &.{
167 .{ .reg = inst.data.rr.r1 },159 .{ .reg = inst.data.rr.r1 },
168 .{ .reg = inst.data.rr.r2 },160 .{ .reg = inst.data.rr.r2 },
169 });161 });
170 },162 },
171 .pseudo_set_nz_or_p_m => {163 .pseudo_set_nz_or_p_m => {
172 assert(inst.data.rx.fixes == ._);164 assert(inst.data.rx.fixes == ._);
173 try lower.emit(.none, .setnz, &.{165 try lower.encode(.none, .setnz, &.{
174 .{ .mem = lower.mem(0, inst.data.rx.payload) },166 .{ .mem = lower.mem(0, inst.data.rx.payload) },
175 });167 });
176 try lower.emit(.none, .setp, &.{168 try lower.encode(.none, .setp, &.{
177 .{ .reg = inst.data.rx.r1 },169 .{ .reg = inst.data.rx.r1 },
178 });170 });
179 try lower.emit(.none, .@"or", &.{171 try lower.encode(.none, .@"or", &.{
180 .{ .mem = lower.mem(0, inst.data.rx.payload) },172 .{ .mem = lower.mem(0, inst.data.rx.payload) },
181 .{ .reg = inst.data.rx.r1 },173 .{ .reg = inst.data.rx.r1 },
182 });174 });
183 },175 },
184 .pseudo_j_z_and_np_inst => {176 .pseudo_j_z_and_np_inst => {
185 assert(inst.data.inst.fixes == ._);177 assert(inst.data.inst.fixes == ._);
186 try lower.emit(.none, .jnz, &.{178 try lower.encode(.none, .jnz, &.{
187 .{ .imm = lower.reloc(0, .{ .inst = index + 1 }, 0) },179 .{ .imm = lower.reloc(0, .{ .inst = index + 1 }, 0) },
188 });180 });
189 try lower.emit(.none, .jnp, &.{181 try lower.encode(.none, .jnp, &.{
190 .{ .imm = lower.reloc(0, .{ .inst = inst.data.inst.inst }, 0) },182 .{ .imm = lower.reloc(0, .{ .inst = inst.data.inst.inst }, 0) },
191 });183 });
192 },184 },
193 .pseudo_j_nz_or_p_inst => {185 .pseudo_j_nz_or_p_inst => {
194 assert(inst.data.inst.fixes == ._);186 assert(inst.data.inst.fixes == ._);
195 try lower.emit(.none, .jnz, &.{187 try lower.encode(.none, .jnz, &.{
196 .{ .imm = lower.reloc(0, .{ .inst = inst.data.inst.inst }, 0) },188 .{ .imm = lower.reloc(0, .{ .inst = inst.data.inst.inst }, 0) },
197 });189 });
198 try lower.emit(.none, .jp, &.{190 try lower.encode(.none, .jp, &.{
199 .{ .imm = lower.reloc(0, .{ .inst = inst.data.inst.inst }, 0) },191 .{ .imm = lower.reloc(0, .{ .inst = inst.data.inst.inst }, 0) },
200 });192 });
201 },193 },
202194
203 .pseudo_probe_align_ri_s => {195 .pseudo_probe_align_ri_s => {
204 try lower.emit(.none, .@"test", &.{196 try lower.encode(.none, .@"test", &.{
205 .{ .reg = inst.data.ri.r1 },197 .{ .reg = inst.data.ri.r1 },
206 .{ .imm = .s(@bitCast(inst.data.ri.i)) },198 .{ .imm = .s(@bitCast(inst.data.ri.i)) },
207 });199 });
208 try lower.emit(.none, .jz, &.{200 try lower.encode(.none, .jz, &.{
209 .{ .imm = lower.reloc(0, .{ .inst = index + 1 }, 0) },201 .{ .imm = lower.reloc(0, .{ .inst = index + 1 }, 0) },
210 });202 });
211 try lower.emit(.none, .lea, &.{203 try lower.encode(.none, .lea, &.{
212 .{ .reg = inst.data.ri.r1 },204 .{ .reg = inst.data.ri.r1 },
213 .{ .mem = Memory.initSib(.qword, .{205 .{ .mem = Memory.initSib(.qword, .{
214 .base = .{ .reg = inst.data.ri.r1 },206 .base = .{ .reg = inst.data.ri.r1 },
215 .disp = -page_size,207 .disp = -page_size,
216 }) },208 }) },
217 });209 });
218 try lower.emit(.none, .@"test", &.{210 try lower.encode(.none, .@"test", &.{
219 .{ .mem = Memory.initSib(.dword, .{211 .{ .mem = Memory.initSib(.dword, .{
220 .base = .{ .reg = inst.data.ri.r1 },212 .base = .{ .reg = inst.data.ri.r1 },
221 }) },213 }) },
222 .{ .reg = inst.data.ri.r1.to32() },214 .{ .reg = inst.data.ri.r1.to32() },
223 });215 });
224 try lower.emit(.none, .jmp, &.{216 try lower.encode(.none, .jmp, &.{
225 .{ .imm = lower.reloc(0, .{ .inst = index }, 0) },217 .{ .imm = lower.reloc(0, .{ .inst = index }, 0) },
226 });218 });
227 assert(lower.result_insts_len == pseudo_probe_align_insts);219 assert(lower.result_insts_len == pseudo_probe_align_insts);
...@@ -229,7 +221,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -229,7 +221,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
229 .pseudo_probe_adjust_unrolled_ri_s => {221 .pseudo_probe_adjust_unrolled_ri_s => {
230 var offset = page_size;222 var offset = page_size;
231 while (offset < @as(i32, @bitCast(inst.data.ri.i))) : (offset += page_size) {223 while (offset < @as(i32, @bitCast(inst.data.ri.i))) : (offset += page_size) {
232 try lower.emit(.none, .@"test", &.{224 try lower.encode(.none, .@"test", &.{
233 .{ .mem = Memory.initSib(.dword, .{225 .{ .mem = Memory.initSib(.dword, .{
234 .base = .{ .reg = inst.data.ri.r1 },226 .base = .{ .reg = inst.data.ri.r1 },
235 .disp = -offset,227 .disp = -offset,
...@@ -237,25 +229,25 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -237,25 +229,25 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
237 .{ .reg = inst.data.ri.r1.to32() },229 .{ .reg = inst.data.ri.r1.to32() },
238 });230 });
239 }231 }
240 try lower.emit(.none, .sub, &.{232 try lower.encode(.none, .sub, &.{
241 .{ .reg = inst.data.ri.r1 },233 .{ .reg = inst.data.ri.r1 },
242 .{ .imm = .s(@bitCast(inst.data.ri.i)) },234 .{ .imm = .s(@bitCast(inst.data.ri.i)) },
243 });235 });
244 assert(lower.result_insts_len <= pseudo_probe_adjust_unrolled_max_insts);236 assert(lower.result_insts_len <= pseudo_probe_adjust_unrolled_max_insts);
245 },237 },
246 .pseudo_probe_adjust_setup_rri_s => {238 .pseudo_probe_adjust_setup_rri_s => {
247 try lower.emit(.none, .mov, &.{239 try lower.encode(.none, .mov, &.{
248 .{ .reg = inst.data.rri.r2.to32() },240 .{ .reg = inst.data.rri.r2.to32() },
249 .{ .imm = .s(@bitCast(inst.data.rri.i)) },241 .{ .imm = .s(@bitCast(inst.data.rri.i)) },
250 });242 });
251 try lower.emit(.none, .sub, &.{243 try lower.encode(.none, .sub, &.{
252 .{ .reg = inst.data.rri.r1 },244 .{ .reg = inst.data.rri.r1 },
253 .{ .reg = inst.data.rri.r2 },245 .{ .reg = inst.data.rri.r2 },
254 });246 });
255 assert(lower.result_insts_len == pseudo_probe_adjust_setup_insts);247 assert(lower.result_insts_len == pseudo_probe_adjust_setup_insts);
256 },248 },
257 .pseudo_probe_adjust_loop_rr => {249 .pseudo_probe_adjust_loop_rr => {
258 try lower.emit(.none, .@"test", &.{250 try lower.encode(.none, .@"test", &.{
259 .{ .mem = Memory.initSib(.dword, .{251 .{ .mem = Memory.initSib(.dword, .{
260 .base = .{ .reg = inst.data.rr.r1 },252 .base = .{ .reg = inst.data.rr.r1 },
261 .scale_index = .{ .scale = 1, .index = inst.data.rr.r2 },253 .scale_index = .{ .scale = 1, .index = inst.data.rr.r2 },
...@@ -263,11 +255,11 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -263,11 +255,11 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
263 }) },255 }) },
264 .{ .reg = inst.data.rr.r1.to32() },256 .{ .reg = inst.data.rr.r1.to32() },
265 });257 });
266 try lower.emit(.none, .sub, &.{258 try lower.encode(.none, .sub, &.{
267 .{ .reg = inst.data.rr.r2 },259 .{ .reg = inst.data.rr.r2 },
268 .{ .imm = .s(page_size) },260 .{ .imm = .s(page_size) },
269 });261 });
270 try lower.emit(.none, .jae, &.{262 try lower.encode(.none, .jae, &.{
271 .{ .imm = lower.reloc(0, .{ .inst = index }, 0) },263 .{ .imm = lower.reloc(0, .{ .inst = index }, 0) },
272 });264 });
273 assert(lower.result_insts_len == pseudo_probe_adjust_loop_insts);265 assert(lower.result_insts_len == pseudo_probe_adjust_loop_insts);
...@@ -275,47 +267,47 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -275,47 +267,47 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
275 .pseudo_push_reg_list => try lower.pushPopRegList(.push, inst),267 .pseudo_push_reg_list => try lower.pushPopRegList(.push, inst),
276 .pseudo_pop_reg_list => try lower.pushPopRegList(.pop, inst),268 .pseudo_pop_reg_list => try lower.pushPopRegList(.pop, inst),
277269
278 .pseudo_cfi_def_cfa_ri_s => try lower.emit(.directive, .@".cfi_def_cfa", &.{270 .pseudo_cfi_def_cfa_ri_s => try lower.encode(.directive, .@".cfi_def_cfa", &.{
279 .{ .reg = inst.data.ri.r1 },271 .{ .reg = inst.data.ri.r1 },
280 .{ .imm = lower.imm(.ri_s, inst.data.ri.i) },272 .{ .imm = lower.imm(.ri_s, inst.data.ri.i) },
281 }),273 }),
282 .pseudo_cfi_def_cfa_register_r => try lower.emit(.directive, .@".cfi_def_cfa_register", &.{274 .pseudo_cfi_def_cfa_register_r => try lower.encode(.directive, .@".cfi_def_cfa_register", &.{
283 .{ .reg = inst.data.r.r1 },275 .{ .reg = inst.data.r.r1 },
284 }),276 }),
285 .pseudo_cfi_def_cfa_offset_i_s => try lower.emit(.directive, .@".cfi_def_cfa_offset", &.{277 .pseudo_cfi_def_cfa_offset_i_s => try lower.encode(.directive, .@".cfi_def_cfa_offset", &.{
286 .{ .imm = lower.imm(.i_s, inst.data.i.i) },278 .{ .imm = lower.imm(.i_s, inst.data.i.i) },
287 }),279 }),
288 .pseudo_cfi_adjust_cfa_offset_i_s => try lower.emit(.directive, .@".cfi_adjust_cfa_offset", &.{280 .pseudo_cfi_adjust_cfa_offset_i_s => try lower.encode(.directive, .@".cfi_adjust_cfa_offset", &.{
289 .{ .imm = lower.imm(.i_s, inst.data.i.i) },281 .{ .imm = lower.imm(.i_s, inst.data.i.i) },
290 }),282 }),
291 .pseudo_cfi_offset_ri_s => try lower.emit(.directive, .@".cfi_offset", &.{283 .pseudo_cfi_offset_ri_s => try lower.encode(.directive, .@".cfi_offset", &.{
292 .{ .reg = inst.data.ri.r1 },284 .{ .reg = inst.data.ri.r1 },
293 .{ .imm = lower.imm(.ri_s, inst.data.ri.i) },285 .{ .imm = lower.imm(.ri_s, inst.data.ri.i) },
294 }),286 }),
295 .pseudo_cfi_val_offset_ri_s => try lower.emit(.directive, .@".cfi_val_offset", &.{287 .pseudo_cfi_val_offset_ri_s => try lower.encode(.directive, .@".cfi_val_offset", &.{
296 .{ .reg = inst.data.ri.r1 },288 .{ .reg = inst.data.ri.r1 },
297 .{ .imm = lower.imm(.ri_s, inst.data.ri.i) },289 .{ .imm = lower.imm(.ri_s, inst.data.ri.i) },
298 }),290 }),
299 .pseudo_cfi_rel_offset_ri_s => try lower.emit(.directive, .@".cfi_rel_offset", &.{291 .pseudo_cfi_rel_offset_ri_s => try lower.encode(.directive, .@".cfi_rel_offset", &.{
300 .{ .reg = inst.data.ri.r1 },292 .{ .reg = inst.data.ri.r1 },
301 .{ .imm = lower.imm(.ri_s, inst.data.ri.i) },293 .{ .imm = lower.imm(.ri_s, inst.data.ri.i) },
302 }),294 }),
303 .pseudo_cfi_register_rr => try lower.emit(.directive, .@".cfi_register", &.{295 .pseudo_cfi_register_rr => try lower.encode(.directive, .@".cfi_register", &.{
304 .{ .reg = inst.data.rr.r1 },296 .{ .reg = inst.data.rr.r1 },
305 .{ .reg = inst.data.rr.r2 },297 .{ .reg = inst.data.rr.r2 },
306 }),298 }),
307 .pseudo_cfi_restore_r => try lower.emit(.directive, .@".cfi_restore", &.{299 .pseudo_cfi_restore_r => try lower.encode(.directive, .@".cfi_restore", &.{
308 .{ .reg = inst.data.r.r1 },300 .{ .reg = inst.data.r.r1 },
309 }),301 }),
310 .pseudo_cfi_undefined_r => try lower.emit(.directive, .@".cfi_undefined", &.{302 .pseudo_cfi_undefined_r => try lower.encode(.directive, .@".cfi_undefined", &.{
311 .{ .reg = inst.data.r.r1 },303 .{ .reg = inst.data.r.r1 },
312 }),304 }),
313 .pseudo_cfi_same_value_r => try lower.emit(.directive, .@".cfi_same_value", &.{305 .pseudo_cfi_same_value_r => try lower.encode(.directive, .@".cfi_same_value", &.{
314 .{ .reg = inst.data.r.r1 },306 .{ .reg = inst.data.r.r1 },
315 }),307 }),
316 .pseudo_cfi_remember_state_none => try lower.emit(.directive, .@".cfi_remember_state", &.{}),308 .pseudo_cfi_remember_state_none => try lower.encode(.directive, .@".cfi_remember_state", &.{}),
317 .pseudo_cfi_restore_state_none => try lower.emit(.directive, .@".cfi_restore_state", &.{}),309 .pseudo_cfi_restore_state_none => try lower.encode(.directive, .@".cfi_restore_state", &.{}),
318 .pseudo_cfi_escape_bytes => try lower.emit(.directive, .@".cfi_escape", &.{310 .pseudo_cfi_escape_bytes => try lower.encode(.directive, .@".cfi_escape", &.{
319 .{ .bytes = inst.data.bytes.get(lower.mir) },311 .{ .bytes = inst.data.bytes.get(lower.mir) },
320 }),312 }),
321313
...@@ -327,16 +319,23 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -327,16 +319,23 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
327 .pseudo_dbg_leave_block_none,319 .pseudo_dbg_leave_block_none,
328 .pseudo_dbg_enter_inline_func,320 .pseudo_dbg_enter_inline_func,
329 .pseudo_dbg_leave_inline_func,321 .pseudo_dbg_leave_inline_func,
330 .pseudo_dbg_local_a,322 .pseudo_dbg_arg_none,
331 .pseudo_dbg_local_ai_s,323 .pseudo_dbg_arg_i_s,
332 .pseudo_dbg_local_ai_u,324 .pseudo_dbg_arg_i_u,
333 .pseudo_dbg_local_ai_64,325 .pseudo_dbg_arg_i_64,
334 .pseudo_dbg_local_as,326 .pseudo_dbg_arg_ro,
335 .pseudo_dbg_local_aso,327 .pseudo_dbg_arg_fa,
336 .pseudo_dbg_local_aro,328 .pseudo_dbg_arg_m,
337 .pseudo_dbg_local_af,329 .pseudo_dbg_arg_val,
338 .pseudo_dbg_local_am,
339 .pseudo_dbg_var_args_none,330 .pseudo_dbg_var_args_none,
331 .pseudo_dbg_var_none,
332 .pseudo_dbg_var_i_s,
333 .pseudo_dbg_var_i_u,
334 .pseudo_dbg_var_i_64,
335 .pseudo_dbg_var_ro,
336 .pseudo_dbg_var_fa,
337 .pseudo_dbg_var_m,
338 .pseudo_dbg_var_val,
340339
341 .pseudo_dead_none,340 .pseudo_dead_none,
342 => {},341 => {},
...@@ -353,7 +352,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -353,7 +352,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
353pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error {352pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error {
354 @branchHint(.cold);353 @branchHint(.cold);
355 assert(lower.err_msg == null);354 assert(lower.err_msg == null);
356 lower.err_msg = try Zcu.ErrorMsg.create(lower.allocator, lower.src_loc, format, args);355 lower.err_msg = try .create(lower.allocator, lower.src_loc, format, args);
357 return error.LowerFail;356 return error.LowerFail;
358}357}
359358
...@@ -364,7 +363,8 @@ pub fn imm(lower: *const Lower, ops: Mir.Inst.Ops, i: u32) Immediate {...@@ -364,7 +363,8 @@ pub fn imm(lower: *const Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
364 .i_s,363 .i_s,
365 .mi_s,364 .mi_s,
366 .rmi_s,365 .rmi_s,
367 .pseudo_dbg_local_ai_s,366 .pseudo_dbg_arg_i_s,
367 .pseudo_dbg_var_i_s,
368 => .s(@bitCast(i)),368 => .s(@bitCast(i)),
369369
370 .ii,370 .ii,
...@@ -379,24 +379,32 @@ pub fn imm(lower: *const Lower, ops: Mir.Inst.Ops, i: u32) Immediate {...@@ -379,24 +379,32 @@ pub fn imm(lower: *const Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
379 .mri,379 .mri,
380 .rrm,380 .rrm,
381 .rrmi,381 .rrmi,
382 .pseudo_dbg_local_ai_u,382 .pseudo_dbg_arg_i_u,
383 .pseudo_dbg_var_i_u,
383 => .u(i),384 => .u(i),
384385
385 .ri_64,386 .ri_64,
386 .pseudo_dbg_local_ai_64,
387 => .u(lower.mir.extraData(Mir.Imm64, i).data.decode()),387 => .u(lower.mir.extraData(Mir.Imm64, i).data.decode()),
388388
389 .pseudo_dbg_arg_i_64,
390 .pseudo_dbg_var_i_64,
391 => unreachable,
392
389 else => unreachable,393 else => unreachable,
390 };394 };
391}395}
392396
393pub fn mem(lower: *Lower, op_index: InstOpIndex, payload: u32) Memory {397fn mem(lower: *Lower, op_index: InstOpIndex, payload: u32) Memory {
394 var m = lower.mir.resolveFrameLoc(lower.mir.extraData(Mir.Memory, payload).data).decode();398 var m = lower.mir.resolveMemoryExtra(payload).decode();
395 switch (m) {399 switch (m) {
396 .sib => |*sib| switch (sib.base) {400 .sib => |*sib| switch (sib.base) {
397 else => {},401 .none, .reg, .frame => {},
398 .table => sib.disp = lower.reloc(op_index, .table, sib.disp).signed,402 .table => sib.disp = lower.reloc(op_index, .table, sib.disp).signed,
399 .rip_inst => |inst_index| sib.disp = lower.reloc(op_index, .{ .inst = inst_index }, sib.disp).signed,403 .rip_inst => |inst_index| sib.disp = lower.reloc(op_index, .{ .inst = inst_index }, sib.disp).signed,
404 .nav => |nav| sib.disp = lower.reloc(op_index, .{ .nav = nav }, sib.disp).signed,
405 .uav => |uav| sib.disp = lower.reloc(op_index, .{ .uav = uav }, sib.disp).signed,
406 .lazy_sym => |lazy_sym| sib.disp = lower.reloc(op_index, .{ .lazy_sym = lazy_sym }, sib.disp).signed,
407 .extern_func => |extern_func| sib.disp = lower.reloc(op_index, .{ .extern_func = extern_func }, sib.disp).signed,
400 },408 },
401 else => {},409 else => {},
402 }410 }
...@@ -414,177 +422,40 @@ fn reloc(lower: *Lower, op_index: InstOpIndex, target: Reloc.Target, off: i32) I...@@ -414,177 +422,40 @@ fn reloc(lower: *Lower, op_index: InstOpIndex, target: Reloc.Target, off: i32) I
414 return .s(0);422 return .s(0);
415}423}
416424
417fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) Error!void {425fn encode(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) Error!void {
418 const emit_prefix = prefix;426 lower.result_insts[lower.result_insts_len] = try .new(prefix, mnemonic, ops, lower.target);
419 var emit_mnemonic = mnemonic;427 lower.result_insts_len += 1;
420 var emit_ops_storage: [4]Operand = undefined;428}
421 const emit_ops = emit_ops_storage[0..ops.len];
422 for (emit_ops, ops, 0..) |*emit_op, op, op_index| {
423 emit_op.* = switch (op) {
424 else => op,
425 .mem => |mem_op| op: switch (mem_op.base()) {
426 else => op,
427 .reloc => |sym_index| {
428 assert(prefix == .none);
429 assert(mem_op.sib.disp == 0);
430 assert(mem_op.sib.scale_index.scale == 0);
431
432 if (lower.bin_file.cast(.elf)) |elf_file| {
433 const zo = elf_file.zigObjectPtr().?;
434 const elf_sym = zo.symbol(sym_index);
435
436 if (elf_sym.flags.is_tls) {
437 // TODO handle extern TLS vars, i.e., emit GD model
438 if (lower.pic) {
439 // Here, we currently assume local dynamic TLS vars, and so
440 // we emit LD model.
441 _ = lower.reloc(1, .{ .linker_tlsld = sym_index }, 0);
442 lower.result_insts[lower.result_insts_len] = try .new(.none, .lea, &.{
443 .{ .reg = .rdi },
444 .{ .mem = Memory.initRip(.none, 0) },
445 }, lower.target);
446 lower.result_insts_len += 1;
447 _ = lower.reloc(0, .{
448 .linker_extern_fn = try elf_file.getGlobalSymbol("__tls_get_addr", null),
449 }, 0);
450 lower.result_insts[lower.result_insts_len] = try .new(.none, .call, &.{
451 .{ .imm = .s(0) },
452 }, lower.target);
453 lower.result_insts_len += 1;
454 _ = lower.reloc(@intCast(op_index), .{ .linker_dtpoff = sym_index }, 0);
455 emit_mnemonic = .lea;
456 break :op .{ .mem = Memory.initSib(.none, .{
457 .base = .{ .reg = .rax },
458 .disp = std.math.minInt(i32),
459 }) };
460 } else {
461 // Since we are linking statically, we emit LE model directly.
462 lower.result_insts[lower.result_insts_len] = try .new(.none, .mov, &.{
463 .{ .reg = .rax },
464 .{ .mem = Memory.initSib(.qword, .{ .base = .{ .reg = .fs } }) },
465 }, lower.target);
466 lower.result_insts_len += 1;
467 _ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
468 emit_mnemonic = .lea;
469 break :op .{ .mem = Memory.initSib(.none, .{
470 .base = .{ .reg = .rax },
471 .disp = std.math.minInt(i32),
472 }) };
473 }
474 }
475
476 if (lower.pic) switch (mnemonic) {
477 .lea => {
478 _ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
479 if (!elf_sym.flags.is_extern_ptr) break :op .{ .mem = Memory.initRip(.none, 0) };
480 emit_mnemonic = .mov;
481 break :op .{ .mem = Memory.initRip(.ptr, 0) };
482 },
483 .mov => {
484 if (elf_sym.flags.is_extern_ptr) {
485 const reg = ops[0].reg;
486 _ = lower.reloc(1, .{ .linker_reloc = sym_index }, 0);
487 lower.result_insts[lower.result_insts_len] = try .new(.none, .mov, &.{
488 .{ .reg = reg.to64() },
489 .{ .mem = Memory.initRip(.qword, 0) },
490 }, lower.target);
491 lower.result_insts_len += 1;
492 break :op .{ .mem = Memory.initSib(mem_op.sib.ptr_size, .{ .base = .{
493 .reg = reg.to64(),
494 } }) };
495 }
496 _ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
497 break :op .{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) };
498 },
499 else => unreachable,
500 };
501 _ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
502 switch (mnemonic) {
503 .call => break :op .{ .mem = Memory.initSib(mem_op.sib.ptr_size, .{
504 .base = .{ .reg = .ds },
505 }) },
506 .lea => {
507 emit_mnemonic = .mov;
508 break :op .{ .imm = .s(0) };
509 },
510 .mov => break :op .{ .mem = Memory.initSib(mem_op.sib.ptr_size, .{
511 .base = .{ .reg = .ds },
512 }) },
513 else => unreachable,
514 }
515 } else if (lower.bin_file.cast(.macho)) |macho_file| {
516 const zo = macho_file.getZigObject().?;
517 const macho_sym = zo.symbols.items[sym_index];
518
519 if (macho_sym.flags.tlv) {
520 _ = lower.reloc(1, .{ .linker_reloc = sym_index }, 0);
521 lower.result_insts[lower.result_insts_len] = try .new(.none, .mov, &.{
522 .{ .reg = .rdi },
523 .{ .mem = Memory.initRip(.ptr, 0) },
524 }, lower.target);
525 lower.result_insts_len += 1;
526 lower.result_insts[lower.result_insts_len] = try .new(.none, .call, &.{
527 .{ .mem = Memory.initSib(.qword, .{ .base = .{ .reg = .rdi } }) },
528 }, lower.target);
529 lower.result_insts_len += 1;
530 emit_mnemonic = .mov;
531 break :op .{ .reg = .rax };
532 }
533
534 break :op switch (mnemonic) {
535 .lea => {
536 _ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
537 if (!macho_sym.flags.is_extern_ptr) break :op .{ .mem = Memory.initRip(.none, 0) };
538 emit_mnemonic = .mov;
539 break :op .{ .mem = Memory.initRip(.ptr, 0) };
540 },
541 .mov => {
542 if (macho_sym.flags.is_extern_ptr) {
543 const reg = ops[0].reg;
544 _ = lower.reloc(1, .{ .linker_reloc = sym_index }, 0);
545 lower.result_insts[lower.result_insts_len] = try .new(.none, .mov, &.{
546 .{ .reg = reg.to64() },
547 .{ .mem = Memory.initRip(.qword, 0) },
548 }, lower.target);
549 lower.result_insts_len += 1;
550 break :op .{ .mem = Memory.initSib(mem_op.sib.ptr_size, .{ .base = .{
551 .reg = reg.to64(),
552 } }) };
553 }
554 _ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
555 break :op .{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) };
556 },
557 else => unreachable,
558 };
559 } else {
560 return lower.fail("TODO: bin format '{s}'", .{@tagName(lower.bin_file.tag)});
561 }
562 },
563 .pcrel => |sym_index| {
564 assert(prefix == .none);
565 assert(mem_op.sib.disp == 0);
566 assert(mem_op.sib.scale_index.scale == 0);
567429
568 _ = lower.reloc(@intCast(op_index), .{ .linker_pcrel = sym_index }, 0);430const inst_tags_len = @typeInfo(Mir.Inst.Tag).@"enum".fields.len;
569 break :op switch (lower.bin_file.tag) {431const inst_fixes_len = @typeInfo(Mir.Inst.Fixes).@"enum".fields.len;
570 .elf => op,432/// Lookup table, indexed by `@intFromEnum(inst.tag) * inst_fixes_len + @intFromEnum(fixes)`.
571 .macho => switch (mnemonic) {433/// The value is the resulting `Mnemonic`, or `null` if the combination is not valid.
572 .lea => .{ .mem = Memory.initRip(.none, 0) },434const mnemonic_table: [inst_tags_len * inst_fixes_len]?Mnemonic = table: {
573 .mov => .{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) },435 @setEvalBranchQuota(80_000);
574 else => unreachable,436 var table: [inst_tags_len * inst_fixes_len]?Mnemonic = undefined;
575 },437 for (0..inst_fixes_len) |fixes_i| {
576 else => |tag| return lower.fail("TODO: bin format '{s}'", .{@tagName(tag)}),438 const fixes: Mir.Inst.Fixes = @enumFromInt(fixes_i);
577 };439 const prefix, const suffix = affix: {
578 },440 const pattern = if (std.mem.indexOfScalar(u8, @tagName(fixes), ' ')) |i|
579 },441 @tagName(fixes)[i + 1 ..]
442 else
443 @tagName(fixes);
444 const wildcard_idx = std.mem.indexOfScalar(u8, pattern, '_').?;
445 break :affix .{ pattern[0..wildcard_idx], pattern[wildcard_idx + 1 ..] };
580 };446 };
447 for (0..inst_tags_len) |inst_tag_i| {
448 const inst_tag: Mir.Inst.Tag = @enumFromInt(inst_tag_i);
449 const name = prefix ++ @tagName(inst_tag) ++ suffix;
450 const idx = inst_tag_i * inst_fixes_len + fixes_i;
451 table[idx] = if (@hasField(Mnemonic, name)) @field(Mnemonic, name) else null;
452 }
581 }453 }
582 lower.result_insts[lower.result_insts_len] = try .new(emit_prefix, emit_mnemonic, emit_ops, lower.target);454 break :table table;
583 lower.result_insts_len += 1;455};
584}
585456
586fn generic(lower: *Lower, inst: Mir.Inst) Error!void {457fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
587 @setEvalBranchQuota(2_800);458 @setEvalBranchQuota(2_000);
588 const fixes = switch (inst.ops) {459 const fixes = switch (inst.ops) {
589 .none => inst.data.none.fixes,460 .none => inst.data.none.fixes,
590 .inst => inst.data.inst.fixes,461 .inst => inst.data.inst.fixes,
...@@ -604,28 +475,27 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -604,28 +475,27 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
604 .rrmi => inst.data.rrix.fixes,475 .rrmi => inst.data.rrix.fixes,
605 .mi_u, .mi_s => inst.data.x.fixes,476 .mi_u, .mi_s => inst.data.x.fixes,
606 .m => inst.data.x.fixes,477 .m => inst.data.x.fixes,
607 .extern_fn_reloc, .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc, .rel => ._,478 .nav, .uav, .lazy_sym, .extern_func => ._,
608 else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}),479 else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}),
609 };480 };
610 try lower.emit(switch (fixes) {481 try lower.encode(switch (fixes) {
611 inline else => |tag| comptime if (std.mem.indexOfScalar(u8, @tagName(tag), ' ')) |space|482 inline else => |tag| comptime if (std.mem.indexOfScalar(u8, @tagName(tag), ' ')) |space|
612 @field(Prefix, @tagName(tag)[0..space])483 @field(Prefix, @tagName(tag)[0..space])
613 else484 else
614 .none,485 .none,
615 }, mnemonic: {486 }, mnemonic: {
616 comptime var max_len = 0;487 if (mnemonic_table[@intFromEnum(inst.tag) * inst_fixes_len + @intFromEnum(fixes)]) |mnemonic| {
617 inline for (@typeInfo(Mnemonic).@"enum".fields) |field| max_len = @max(field.name.len, max_len);488 break :mnemonic mnemonic;
618 var buf: [max_len]u8 = undefined;489 }
619490 // This combination is invalid; make the theoretical mnemonic name and emit an error with it.
620 const fixes_name = @tagName(fixes);491 const fixes_name = @tagName(fixes);
621 const pattern = fixes_name[if (std.mem.indexOfScalar(u8, fixes_name, ' ')) |i| i + " ".len else 0..];492 const pattern = fixes_name[if (std.mem.indexOfScalar(u8, fixes_name, ' ')) |i| i + " ".len else 0..];
622 const wildcard_index = std.mem.indexOfScalar(u8, pattern, '_').?;493 const wildcard_index = std.mem.indexOfScalar(u8, pattern, '_').?;
623 const parts = .{ pattern[0..wildcard_index], @tagName(inst.tag), pattern[wildcard_index + "_".len ..] };494 return lower.fail("unsupported mnemonic: '{s}{s}{s}'", .{
624 const err_msg = "unsupported mnemonic: ";495 pattern[0..wildcard_index],
625 const mnemonic = std.fmt.bufPrint(&buf, "{s}{s}{s}", parts) catch496 @tagName(inst.tag),
626 return lower.fail(err_msg ++ "'{s}{s}{s}'", parts);497 pattern[wildcard_index + "_".len ..],
627 break :mnemonic std.meta.stringToEnum(Mnemonic, mnemonic) orelse498 });
628 return lower.fail(err_msg ++ "'{s}'", .{mnemonic});
629 }, switch (inst.ops) {499 }, switch (inst.ops) {
630 .none => &.{},500 .none => &.{},
631 .inst => &.{501 .inst => &.{
...@@ -738,22 +608,17 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -738,22 +608,17 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
738 .{ .mem = lower.mem(2, inst.data.rrix.payload) },608 .{ .mem = lower.mem(2, inst.data.rrix.payload) },
739 .{ .imm = lower.imm(inst.ops, inst.data.rrix.i) },609 .{ .imm = lower.imm(inst.ops, inst.data.rrix.i) },
740 },610 },
741 .extern_fn_reloc, .rel => &.{611 .nav => &.{
742 .{ .imm = lower.reloc(0, .{ .linker_extern_fn = inst.data.reloc.sym_index }, inst.data.reloc.off) },612 .{ .imm = lower.reloc(0, .{ .nav = inst.data.nav.index }, inst.data.nav.off) },
743 },613 },
744 .got_reloc, .direct_reloc, .import_reloc => ops: {614 .uav => &.{
745 const reg = inst.data.rx.r1;615 .{ .imm = lower.reloc(0, .{ .uav = inst.data.uav }, 0) },
746 const extra = lower.mir.extraData(bits.SymbolOffset, inst.data.rx.payload).data;616 },
747 _ = lower.reloc(1, switch (inst.ops) {617 .lazy_sym => &.{
748 .got_reloc => .{ .linker_got = extra.sym_index },618 .{ .imm = lower.reloc(0, .{ .lazy_sym = inst.data.lazy_sym }, 0) },
749 .direct_reloc => .{ .linker_direct = extra.sym_index },619 },
750 .import_reloc => .{ .linker_import = extra.sym_index },620 .extern_func => &.{
751 else => unreachable,621 .{ .imm = lower.reloc(0, .{ .extern_func = inst.data.extern_func }, 0) },
752 }, extra.off);
753 break :ops &.{
754 .{ .reg = reg },
755 .{ .mem = Memory.initRip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) },
756 };
757 },622 },
758 else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }),623 else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }),
759 });624 });
...@@ -773,7 +638,7 @@ fn pushPopRegList(lower: *Lower, comptime mnemonic: Mnemonic, inst: Mir.Inst) Er...@@ -773,7 +638,7 @@ fn pushPopRegList(lower: *Lower, comptime mnemonic: Mnemonic, inst: Mir.Inst) Er
773 else => unreachable,638 else => unreachable,
774 } });639 } });
775 while (it.next()) |i| {640 while (it.next()) |i| {
776 try lower.emit(.none, mnemonic, &.{.{641 try lower.encode(.none, mnemonic, &.{.{
777 .reg = callee_preserved_regs[i],642 .reg = callee_preserved_regs[i],
778 }});643 }});
779 switch (mnemonic) {644 switch (mnemonic) {
...@@ -787,7 +652,7 @@ fn pushPopRegList(lower: *Lower, comptime mnemonic: Mnemonic, inst: Mir.Inst) Er...@@ -787,7 +652,7 @@ fn pushPopRegList(lower: *Lower, comptime mnemonic: Mnemonic, inst: Mir.Inst) Er
787 .push => {652 .push => {
788 var it = inst.data.reg_list.iterator(.{});653 var it = inst.data.reg_list.iterator(.{});
789 while (it.next()) |i| {654 while (it.next()) |i| {
790 try lower.emit(.directive, .@".cfi_rel_offset", &.{655 try lower.encode(.directive, .@".cfi_rel_offset", &.{
791 .{ .reg = callee_preserved_regs[i] },656 .{ .reg = callee_preserved_regs[i] },
792 .{ .imm = .s(off) },657 .{ .imm = .s(off) },
793 });658 });
...@@ -805,12 +670,14 @@ const page_size: i32 = 1 << 12;...@@ -805,12 +670,14 @@ const page_size: i32 = 1 << 12;
805const abi = @import("abi.zig");670const abi = @import("abi.zig");
806const assert = std.debug.assert;671const assert = std.debug.assert;
807const bits = @import("bits.zig");672const bits = @import("bits.zig");
673const codegen = @import("../../codegen.zig");
808const encoder = @import("encoder.zig");674const encoder = @import("encoder.zig");
809const link = @import("../../link.zig");675const link = @import("../../link.zig");
810const std = @import("std");676const std = @import("std");
811677
812const Immediate = Instruction.Immediate;678const Immediate = Instruction.Immediate;
813const Instruction = encoder.Instruction;679const Instruction = encoder.Instruction;
680const InternPool = @import("../../InternPool.zig");
814const Lower = @This();681const Lower = @This();
815const Memory = Instruction.Memory;682const Memory = Instruction.Memory;
816const Mir = @import("Mir.zig");683const Mir = @import("Mir.zig");
...@@ -819,3 +686,4 @@ const Zcu = @import("../../Zcu.zig");...@@ -819,3 +686,4 @@ const Zcu = @import("../../Zcu.zig");
819const Operand = Instruction.Operand;686const Operand = Instruction.Operand;
820const Prefix = Instruction.Prefix;687const Prefix = Instruction.Prefix;
821const Register = bits.Register;688const Register = bits.Register;
689const Type = @import("../../Type.zig");
src/arch/x86_64/Mir.zig+242-82
...@@ -9,6 +9,8 @@...@@ -9,6 +9,8 @@
9instructions: std.MultiArrayList(Inst).Slice,9instructions: std.MultiArrayList(Inst).Slice,
10/// The meaning of this data is determined by `Inst.Tag` value.10/// The meaning of this data is determined by `Inst.Tag` value.
11extra: []const u32,11extra: []const u32,
12string_bytes: []const u8,
13locals: []const Local,
12table: []const Inst.Index,14table: []const Inst.Index,
13frame_locs: std.MultiArrayList(FrameLoc).Slice,15frame_locs: std.MultiArrayList(FrameLoc).Slice,
1416
...@@ -1361,9 +1363,6 @@ pub const Inst = struct {...@@ -1361,9 +1363,6 @@ pub const Inst = struct {
1361 /// Immediate (byte), register operands.1363 /// Immediate (byte), register operands.
1362 /// Uses `ri` payload.1364 /// Uses `ri` payload.
1363 ir,1365 ir,
1364 /// Relative displacement operand.
1365 /// Uses `reloc` payload.
1366 rel,
1367 /// Register, memory operands.1366 /// Register, memory operands.
1368 /// Uses `rx` payload with extra data of type `Memory`.1367 /// Uses `rx` payload with extra data of type `Memory`.
1369 rm,1368 rm,
...@@ -1409,21 +1408,18 @@ pub const Inst = struct {...@@ -1409,21 +1408,18 @@ pub const Inst = struct {
1409 /// References another Mir instruction directly.1408 /// References another Mir instruction directly.
1410 /// Uses `inst` payload.1409 /// Uses `inst` payload.
1411 inst,1410 inst,
1412 /// Linker relocation - external function.1411 /// References a nav.
1413 /// Uses `reloc` payload.1412 /// Uses `nav` payload.
1414 extern_fn_reloc,1413 nav,
1415 /// Linker relocation - GOT indirection.1414 /// References an uav.
1416 /// Uses `rx` payload with extra data of type `bits.SymbolOffset`.1415 /// Uses `uav` payload.
1417 got_reloc,1416 uav,
1418 /// Linker relocation - direct reference.1417 /// References a lazy symbol.
1419 /// Uses `rx` payload with extra data of type `bits.SymbolOffset`.1418 /// Uses `lazy_sym` payload.
1420 direct_reloc,1419 lazy_sym,
1421 /// Linker relocation - imports table indirection (binding).1420 /// References an external symbol.
1422 /// Uses `rx` payload with extra data of type `bits.SymbolOffset`.1421 /// Uses `extern_func` payload.
1423 import_reloc,1422 extern_func,
1424 /// Linker relocation - threadlocal variable via GOT indirection.
1425 /// Uses `rx` payload with extra data of type `bits.SymbolOffset`.
1426 tlv_reloc,
14271423
1428 // Pseudo instructions:1424 // Pseudo instructions:
14291425
...@@ -1522,6 +1518,7 @@ pub const Inst = struct {...@@ -1522,6 +1518,7 @@ pub const Inst = struct {
1522 pseudo_cfi_escape_bytes,1518 pseudo_cfi_escape_bytes,
15231519
1524 /// End of prologue1520 /// End of prologue
1521 /// Uses `none` payload.
1525 pseudo_dbg_prologue_end_none,1522 pseudo_dbg_prologue_end_none,
1526 /// Update debug line with is_stmt register set1523 /// Update debug line with is_stmt register set
1527 /// Uses `line_column` payload.1524 /// Uses `line_column` payload.
...@@ -1530,44 +1527,70 @@ pub const Inst = struct {...@@ -1530,44 +1527,70 @@ pub const Inst = struct {
1530 /// Uses `line_column` payload.1527 /// Uses `line_column` payload.
1531 pseudo_dbg_line_line_column,1528 pseudo_dbg_line_line_column,
1532 /// Start of epilogue1529 /// Start of epilogue
1530 /// Uses `none` payload.
1533 pseudo_dbg_epilogue_begin_none,1531 pseudo_dbg_epilogue_begin_none,
1534 /// Start of lexical block1532 /// Start of lexical block
1533 /// Uses `none` payload.
1535 pseudo_dbg_enter_block_none,1534 pseudo_dbg_enter_block_none,
1536 /// End of lexical block1535 /// End of lexical block
1536 /// Uses `none` payload.
1537 pseudo_dbg_leave_block_none,1537 pseudo_dbg_leave_block_none,
1538 /// Start of inline function1538 /// Start of inline function
1539 /// Uses `ip_index` payload.
1539 pseudo_dbg_enter_inline_func,1540 pseudo_dbg_enter_inline_func,
1540 /// End of inline function1541 /// End of inline function
1542 /// Uses `ip_index` payload.
1541 pseudo_dbg_leave_inline_func,1543 pseudo_dbg_leave_inline_func,
1542 /// Local argument or variable.1544 /// Local argument.
1543 /// Uses `a` payload.1545 /// Uses `none` payload.
1544 pseudo_dbg_local_a,1546 pseudo_dbg_arg_none,
1545 /// Local argument or variable.1547 /// Local argument.
1546 /// Uses `ai` payload.1548 /// Uses `i` payload.
1547 pseudo_dbg_local_ai_s,1549 pseudo_dbg_arg_i_s,
1548 /// Local argument or variable.1550 /// Local argument.
1549 /// Uses `ai` payload.1551 /// Uses `i` payload.
1550 pseudo_dbg_local_ai_u,1552 pseudo_dbg_arg_i_u,
1551 /// Local argument or variable.1553 /// Local argument.
1552 /// Uses `ai` payload with extra data of type `Imm64`.1554 /// Uses `i64` payload.
1553 pseudo_dbg_local_ai_64,1555 pseudo_dbg_arg_i_64,
1554 /// Local argument or variable.1556 /// Local argument.
1555 /// Uses `as` payload.1557 /// Uses `ro` payload.
1556 pseudo_dbg_local_as,1558 pseudo_dbg_arg_ro,
1557 /// Local argument or variable.1559 /// Local argument.
1558 /// Uses `ax` payload with extra data of type `bits.SymbolOffset`.1560 /// Uses `fa` payload.
1559 pseudo_dbg_local_aso,1561 pseudo_dbg_arg_fa,
1560 /// Local argument or variable.1562 /// Local argument.
1561 /// Uses `rx` payload with extra data of type `AirOffset`.1563 /// Uses `x` payload with extra data of type `Memory`.
1562 pseudo_dbg_local_aro,1564 pseudo_dbg_arg_m,
1563 /// Local argument or variable.1565 /// Local argument.
1564 /// Uses `ax` payload with extra data of type `bits.FrameAddr`.1566 /// Uses `ip_index` payload.
1565 pseudo_dbg_local_af,1567 pseudo_dbg_arg_val,
1566 /// Local argument or variable.
1567 /// Uses `ax` payload with extra data of type `Memory`.
1568 pseudo_dbg_local_am,
1569 /// Remaining arguments are varargs.1568 /// Remaining arguments are varargs.
1570 pseudo_dbg_var_args_none,1569 pseudo_dbg_var_args_none,
1570 /// Local variable.
1571 /// Uses `none` payload.
1572 pseudo_dbg_var_none,
1573 /// Local variable.
1574 /// Uses `i` payload.
1575 pseudo_dbg_var_i_s,
1576 /// Local variable.
1577 /// Uses `i` payload.
1578 pseudo_dbg_var_i_u,
1579 /// Local variable.
1580 /// Uses `i64` payload.
1581 pseudo_dbg_var_i_64,
1582 /// Local variable.
1583 /// Uses `ro` payload.
1584 pseudo_dbg_var_ro,
1585 /// Local variable.
1586 /// Uses `fa` payload.
1587 pseudo_dbg_var_fa,
1588 /// Local variable.
1589 /// Uses `x` payload with extra data of type `Memory`.
1590 pseudo_dbg_var_m,
1591 /// Local variable.
1592 /// Uses `ip_index` payload.
1593 pseudo_dbg_var_val,
15711594
1572 /// Tombstone1595 /// Tombstone
1573 /// Emitter should skip this instruction.1596 /// Emitter should skip this instruction.
...@@ -1584,6 +1607,7 @@ pub const Inst = struct {...@@ -1584,6 +1607,7 @@ pub const Inst = struct {
1584 inst: Index,1607 inst: Index,
1585 },1608 },
1586 /// A 32-bit immediate value.1609 /// A 32-bit immediate value.
1610 i64: u64,
1587 i: struct {1611 i: struct {
1588 fixes: Fixes = ._,1612 fixes: Fixes = ._,
1589 i: u32,1613 i: u32,
...@@ -1683,31 +1707,18 @@ pub const Inst = struct {...@@ -1683,31 +1707,18 @@ pub const Inst = struct {
1683 return std.mem.sliceAsBytes(mir.extra[bytes.payload..])[0..bytes.len];1707 return std.mem.sliceAsBytes(mir.extra[bytes.payload..])[0..bytes.len];
1684 }1708 }
1685 },1709 },
1686 a: struct {1710 fa: bits.FrameAddr,
1687 air_inst: Air.Inst.Index,1711 ro: bits.RegisterOffset,
1688 },1712 nav: bits.NavOffset,
1689 ai: struct {1713 uav: InternPool.Key.Ptr.BaseAddr.Uav,
1690 air_inst: Air.Inst.Index,1714 lazy_sym: link.File.LazySymbol,
1691 i: u32,1715 extern_func: Mir.NullTerminatedString,
1692 },
1693 as: struct {
1694 air_inst: Air.Inst.Index,
1695 sym_index: u32,
1696 },
1697 ax: struct {
1698 air_inst: Air.Inst.Index,
1699 payload: u32,
1700 },
1701 /// Relocation for the linker where:
1702 /// * `sym_index` is the index of the target
1703 /// * `off` is the offset from the target
1704 reloc: bits.SymbolOffset,
1705 /// Debug line and column position1716 /// Debug line and column position
1706 line_column: struct {1717 line_column: struct {
1707 line: u32,1718 line: u32,
1708 column: u32,1719 column: u32,
1709 },1720 },
1710 func: InternPool.Index,1721 ip_index: InternPool.Index,
1711 /// Register list1722 /// Register list
1712 reg_list: RegisterList,1723 reg_list: RegisterList,
1713 };1724 };
...@@ -1760,13 +1771,11 @@ pub const Inst = struct {...@@ -1760,13 +1771,11 @@ pub const Inst = struct {
1760 }1771 }
1761};1772};
17621773
1763pub const AirOffset = struct { air_inst: Air.Inst.Index, off: i32 };
1764
1765/// Used in conjunction with payload to transfer a list of used registers in a compact manner.1774/// Used in conjunction with payload to transfer a list of used registers in a compact manner.
1766pub const RegisterList = struct {1775pub const RegisterList = struct {
1767 bitset: BitSet,1776 bitset: BitSet,
17681777
1769 const BitSet = IntegerBitSet(32);1778 const BitSet = std.bit_set.IntegerBitSet(32);
1770 const Self = @This();1779 const Self = @This();
17711780
1772 pub const empty: RegisterList = .{ .bitset = .initEmpty() };1781 pub const empty: RegisterList = .{ .bitset = .initEmpty() };
...@@ -1805,6 +1814,22 @@ pub const RegisterList = struct {...@@ -1805,6 +1814,22 @@ pub const RegisterList = struct {
1805 }1814 }
1806};1815};
18071816
1817pub const NullTerminatedString = enum(u32) {
1818 none = std.math.maxInt(u32),
1819 _,
1820
1821 pub fn toSlice(nts: NullTerminatedString, mir: *const Mir) ?[:0]const u8 {
1822 if (nts == .none) return null;
1823 const string_bytes = mir.string_bytes[@intFromEnum(nts)..];
1824 return string_bytes[0..std.mem.indexOfScalar(u8, string_bytes, 0).? :0];
1825 }
1826};
1827
1828pub const Local = struct {
1829 name: NullTerminatedString,
1830 type: InternPool.Index,
1831};
1832
1808pub const Imm32 = struct {1833pub const Imm32 = struct {
1809 imm: u32,1834 imm: u32,
1810};1835};
...@@ -1840,11 +1865,10 @@ pub const Memory = struct {...@@ -1840,11 +1865,10 @@ pub const Memory = struct {
1840 size: bits.Memory.Size,1865 size: bits.Memory.Size,
1841 index: Register,1866 index: Register,
1842 scale: bits.Memory.Scale,1867 scale: bits.Memory.Scale,
1843 _: u14 = undefined,1868 _: u13 = undefined,
1844 };1869 };
18451870
1846 pub fn encode(mem: bits.Memory) Memory {1871 pub fn encode(mem: bits.Memory) Memory {
1847 assert(mem.base != .reloc or mem.mod != .off);
1848 return .{1872 return .{
1849 .info = .{1873 .info = .{
1850 .base = mem.base,1874 .base = mem.base,
...@@ -1866,17 +1890,27 @@ pub const Memory = struct {...@@ -1866,17 +1890,27 @@ pub const Memory = struct {
1866 .none, .table => undefined,1890 .none, .table => undefined,
1867 .reg => |reg| @intFromEnum(reg),1891 .reg => |reg| @intFromEnum(reg),
1868 .frame => |frame_index| @intFromEnum(frame_index),1892 .frame => |frame_index| @intFromEnum(frame_index),
1869 .reloc, .pcrel => |sym_index| sym_index,
1870 .rip_inst => |inst_index| inst_index,1893 .rip_inst => |inst_index| inst_index,
1894 .nav => |nav| @intFromEnum(nav),
1895 .uav => |uav| @intFromEnum(uav.val),
1896 .lazy_sym => |lazy_sym| @intFromEnum(lazy_sym.ty),
1897 .extern_func => |extern_func| @intFromEnum(extern_func),
1871 },1898 },
1872 .off = switch (mem.mod) {1899 .off = switch (mem.mod) {
1873 .rm => |rm| @bitCast(rm.disp),1900 .rm => |rm| @bitCast(rm.disp),
1874 .off => |off| @truncate(off),1901 .off => |off| @truncate(off),
1875 },1902 },
1876 .extra = if (mem.mod == .off)1903 .extra = switch (mem.mod) {
1877 @intCast(mem.mod.off >> 32)1904 .rm => switch (mem.base) {
1878 else1905 else => undefined,
1879 undefined,1906 .uav => |uav| @intFromEnum(uav.orig_ty),
1907 .lazy_sym => |lazy_sym| @intFromEnum(lazy_sym.kind),
1908 },
1909 .off => switch (mem.base) {
1910 .reg => @intCast(mem.mod.off >> 32),
1911 else => unreachable,
1912 },
1913 },
1880 };1914 };
1881 }1915 }
18821916
...@@ -1894,9 +1928,11 @@ pub const Memory = struct {...@@ -1894,9 +1928,11 @@ pub const Memory = struct {
1894 .reg => .{ .reg = @enumFromInt(mem.base) },1928 .reg => .{ .reg = @enumFromInt(mem.base) },
1895 .frame => .{ .frame = @enumFromInt(mem.base) },1929 .frame => .{ .frame = @enumFromInt(mem.base) },
1896 .table => .table,1930 .table => .table,
1897 .reloc => .{ .reloc = mem.base },
1898 .pcrel => .{ .pcrel = mem.base },
1899 .rip_inst => .{ .rip_inst = mem.base },1931 .rip_inst => .{ .rip_inst = mem.base },
1932 .nav => .{ .nav = @enumFromInt(mem.base) },
1933 .uav => .{ .uav = .{ .val = @enumFromInt(mem.base), .orig_ty = @enumFromInt(mem.extra) } },
1934 .lazy_sym => .{ .lazy_sym = .{ .kind = @enumFromInt(mem.extra), .ty = @enumFromInt(mem.base) } },
1935 .extern_func => .{ .extern_func = @enumFromInt(mem.base) },
1900 },1936 },
1901 .scale_index = switch (mem.info.index) {1937 .scale_index = switch (mem.info.index) {
1902 .none => null,1938 .none => null,
...@@ -1924,11 +1960,132 @@ pub const Memory = struct {...@@ -1924,11 +1960,132 @@ pub const Memory = struct {
1924pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {1960pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
1925 mir.instructions.deinit(gpa);1961 mir.instructions.deinit(gpa);
1926 gpa.free(mir.extra);1962 gpa.free(mir.extra);
1963 gpa.free(mir.string_bytes);
1964 gpa.free(mir.locals);
1927 gpa.free(mir.table);1965 gpa.free(mir.table);
1928 mir.frame_locs.deinit(gpa);1966 mir.frame_locs.deinit(gpa);
1929 mir.* = undefined;1967 mir.* = undefined;
1930}1968}
19311969
1970pub fn emit(
1971 mir: Mir,
1972 lf: *link.File,
1973 pt: Zcu.PerThread,
1974 src_loc: Zcu.LazySrcLoc,
1975 func_index: InternPool.Index,
1976 code: *std.ArrayListUnmanaged(u8),
1977 debug_output: link.File.DebugInfoOutput,
1978) codegen.CodeGenError!void {
1979 const zcu = pt.zcu;
1980 const comp = zcu.comp;
1981 const gpa = comp.gpa;
1982 const func = zcu.funcInfo(func_index);
1983 const fn_info = zcu.typeToFunc(.fromInterned(func.ty)).?;
1984 const nav = func.owner_nav;
1985 const mod = zcu.navFileScope(nav).mod.?;
1986 var e: Emit = .{
1987 .lower = .{
1988 .target = &mod.resolved_target.result,
1989 .allocator = gpa,
1990 .mir = mir,
1991 .cc = fn_info.cc,
1992 .src_loc = src_loc,
1993 },
1994 .bin_file = lf,
1995 .pt = pt,
1996 .pic = mod.pic,
1997 .atom_index = sym: {
1998 if (lf.cast(.elf)) |ef| break :sym try ef.zigObjectPtr().?.getOrCreateMetadataForNav(zcu, nav);
1999 if (lf.cast(.macho)) |mf| break :sym try mf.getZigObject().?.getOrCreateMetadataForNav(mf, nav);
2000 if (lf.cast(.coff)) |cf| {
2001 const atom = try cf.getOrCreateAtomForNav(nav);
2002 break :sym cf.getAtom(atom).getSymbolIndex().?;
2003 }
2004 if (lf.cast(.plan9)) |p9f| break :sym try p9f.seeNav(pt, nav);
2005 unreachable;
2006 },
2007 .debug_output = debug_output,
2008 .code = code,
2009
2010 .prev_di_loc = .{
2011 .line = func.lbrace_line,
2012 .column = func.lbrace_column,
2013 .is_stmt = switch (debug_output) {
2014 .dwarf => |dwarf| dwarf.dwarf.debug_line.header.default_is_stmt,
2015 .plan9 => undefined,
2016 .none => undefined,
2017 },
2018 },
2019 .prev_di_pc = 0,
2020
2021 .code_offset_mapping = .empty,
2022 .relocs = .empty,
2023 .table_relocs = .empty,
2024 };
2025 defer e.deinit();
2026 e.emitMir() catch |err| switch (err) {
2027 error.LowerFail, error.EmitFail => return zcu.codegenFailMsg(nav, e.lower.err_msg.?),
2028 error.InvalidInstruction, error.CannotEncode => return zcu.codegenFail(nav, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}),
2029 else => return zcu.codegenFail(nav, "emit MIR failed: {s}", .{@errorName(err)}),
2030 };
2031}
2032
2033pub fn emitLazy(
2034 mir: Mir,
2035 lf: *link.File,
2036 pt: Zcu.PerThread,
2037 src_loc: Zcu.LazySrcLoc,
2038 lazy_sym: link.File.LazySymbol,
2039 code: *std.ArrayListUnmanaged(u8),
2040 debug_output: link.File.DebugInfoOutput,
2041) codegen.CodeGenError!void {
2042 const zcu = pt.zcu;
2043 const comp = zcu.comp;
2044 const gpa = comp.gpa;
2045 const mod = comp.root_mod;
2046 var e: Emit = .{
2047 .lower = .{
2048 .target = &mod.resolved_target.result,
2049 .allocator = gpa,
2050 .mir = mir,
2051 .cc = .auto,
2052 .src_loc = src_loc,
2053 },
2054 .bin_file = lf,
2055 .pt = pt,
2056 .pic = mod.pic,
2057 .atom_index = sym: {
2058 if (lf.cast(.elf)) |ef| break :sym ef.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(ef, pt, lazy_sym) catch |err|
2059 return zcu.codegenFailType(lazy_sym.ty, "{s} creating lazy symbol", .{@errorName(err)});
2060 if (lf.cast(.macho)) |mf| break :sym mf.getZigObject().?.getOrCreateMetadataForLazySymbol(mf, pt, lazy_sym) catch |err|
2061 return zcu.codegenFailType(lazy_sym.ty, "{s} creating lazy symbol", .{@errorName(err)});
2062 if (lf.cast(.coff)) |cf| {
2063 const atom = cf.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
2064 return zcu.codegenFailType(lazy_sym.ty, "{s} creating lazy symbol", .{@errorName(err)});
2065 break :sym cf.getAtom(atom).getSymbolIndex().?;
2066 }
2067 if (lf.cast(.plan9)) |p9f| break :sym p9f.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
2068 return zcu.codegenFailType(lazy_sym.ty, "{s} creating lazy symbol", .{@errorName(err)});
2069 unreachable;
2070 },
2071 .debug_output = debug_output,
2072 .code = code,
2073
2074 .prev_di_loc = undefined,
2075 .prev_di_pc = undefined,
2076
2077 .code_offset_mapping = .empty,
2078 .relocs = .empty,
2079 .table_relocs = .empty,
2080 };
2081 defer e.deinit();
2082 e.emitMir() catch |err| switch (err) {
2083 error.LowerFail, error.EmitFail => return zcu.codegenFailTypeMsg(lazy_sym.ty, e.lower.err_msg.?),
2084 error.InvalidInstruction, error.CannotEncode => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}),
2085 else => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s}", .{@errorName(err)}),
2086 };
2087}
2088
1932pub fn extraData(mir: Mir, comptime T: type, index: u32) struct { data: T, end: u32 } {2089pub fn extraData(mir: Mir, comptime T: type, index: u32) struct { data: T, end: u32 } {
1933 const fields = std.meta.fields(T);2090 const fields = std.meta.fields(T);
1934 var i: u32 = index;2091 var i: u32 = index;
...@@ -1937,7 +2094,7 @@ pub fn extraData(mir: Mir, comptime T: type, index: u32) struct { data: T, end:...@@ -1937,7 +2094,7 @@ pub fn extraData(mir: Mir, comptime T: type, index: u32) struct { data: T, end:
1937 @field(result, field.name) = switch (field.type) {2094 @field(result, field.name) = switch (field.type) {
1938 u32 => mir.extra[i],2095 u32 => mir.extra[i],
1939 i32, Memory.Info => @bitCast(mir.extra[i]),2096 i32, Memory.Info => @bitCast(mir.extra[i]),
1940 bits.FrameIndex, Air.Inst.Index => @enumFromInt(mir.extra[i]),2097 bits.FrameIndex => @enumFromInt(mir.extra[i]),
1941 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),2098 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
1942 };2099 };
1943 i += 1;2100 i += 1;
...@@ -1958,9 +2115,10 @@ pub fn resolveFrameAddr(mir: Mir, frame_addr: bits.FrameAddr) bits.RegisterOffse...@@ -1958,9 +2115,10 @@ pub fn resolveFrameAddr(mir: Mir, frame_addr: bits.FrameAddr) bits.RegisterOffse
1958 return .{ .reg = frame_loc.base, .off = frame_loc.disp + frame_addr.off };2115 return .{ .reg = frame_loc.base, .off = frame_loc.disp + frame_addr.off };
1959}2116}
19602117
1961pub fn resolveFrameLoc(mir: Mir, mem: Memory) Memory {2118pub fn resolveMemoryExtra(mir: Mir, payload: u32) Memory {
2119 const mem = mir.extraData(Mir.Memory, payload).data;
1962 return switch (mem.info.base) {2120 return switch (mem.info.base) {
1963 .none, .reg, .table, .reloc, .pcrel, .rip_inst => mem,2121 .none, .reg, .table, .rip_inst, .nav, .uav, .lazy_sym, .extern_func => mem,
1964 .frame => if (mir.frame_locs.len > 0) .{2122 .frame => if (mir.frame_locs.len > 0) .{
1965 .info = .{2123 .info = .{
1966 .base = .reg,2124 .base = .reg,
...@@ -1982,8 +2140,10 @@ const builtin = @import("builtin");...@@ -1982,8 +2140,10 @@ const builtin = @import("builtin");
1982const encoder = @import("encoder.zig");2140const encoder = @import("encoder.zig");
1983const std = @import("std");2141const std = @import("std");
19842142
1985const Air = @import("../../Air.zig");
1986const IntegerBitSet = std.bit_set.IntegerBitSet;
1987const InternPool = @import("../../InternPool.zig");2143const InternPool = @import("../../InternPool.zig");
1988const Mir = @This();2144const Mir = @This();
1989const Register = bits.Register;2145const Register = bits.Register;
2146const Emit = @import("Emit.zig");
2147const codegen = @import("../../codegen.zig");
2148const link = @import("../../link.zig");
2149const Zcu = @import("../../Zcu.zig");
src/arch/x86_64/bits.zig+16-12
...@@ -4,6 +4,8 @@ const expect = std.testing.expect;...@@ -4,6 +4,8 @@ const expect = std.testing.expect;
44
5const Allocator = std.mem.Allocator;5const Allocator = std.mem.Allocator;
6const ArrayList = std.ArrayList;6const ArrayList = std.ArrayList;
7const InternPool = @import("../../InternPool.zig");
8const link = @import("../../link.zig");
7const Mir = @import("Mir.zig");9const Mir = @import("Mir.zig");
810
9/// EFLAGS condition codes11/// EFLAGS condition codes
...@@ -684,8 +686,6 @@ test "Register id - different classes" {...@@ -684,8 +686,6 @@ test "Register id - different classes" {
684 try expect(Register.xmm0.id() == Register.ymm0.id());686 try expect(Register.xmm0.id() == Register.ymm0.id());
685 try expect(Register.xmm0.id() != Register.mm0.id());687 try expect(Register.xmm0.id() != Register.mm0.id());
686 try expect(Register.mm0.id() != Register.st0.id());688 try expect(Register.mm0.id() != Register.st0.id());
687
688 try expect(Register.es.id() == 0b110000);
689}689}
690690
691test "Register enc - different classes" {691test "Register enc - different classes" {
...@@ -750,20 +750,22 @@ pub const FrameAddr = struct { index: FrameIndex, off: i32 = 0 };...@@ -750,20 +750,22 @@ pub const FrameAddr = struct { index: FrameIndex, off: i32 = 0 };
750750
751pub const RegisterOffset = struct { reg: Register, off: i32 = 0 };751pub const RegisterOffset = struct { reg: Register, off: i32 = 0 };
752752
753pub const SymbolOffset = struct { sym_index: u32, off: i32 = 0 };753pub const NavOffset = struct { index: InternPool.Nav.Index, off: i32 = 0 };
754754
755pub const Memory = struct {755pub const Memory = struct {
756 base: Base = .none,756 base: Base = .none,
757 mod: Mod = .{ .rm = .{} },757 mod: Mod = .{ .rm = .{} },
758758
759 pub const Base = union(enum(u3)) {759 pub const Base = union(enum(u4)) {
760 none,760 none,
761 reg: Register,761 reg: Register,
762 frame: FrameIndex,762 frame: FrameIndex,
763 table,763 table,
764 reloc: u32,
765 pcrel: u32,
766 rip_inst: Mir.Inst.Index,764 rip_inst: Mir.Inst.Index,
765 nav: InternPool.Nav.Index,
766 uav: InternPool.Key.Ptr.BaseAddr.Uav,
767 lazy_sym: link.File.LazySymbol,
768 extern_func: Mir.NullTerminatedString,
767769
768 pub const Tag = @typeInfo(Base).@"union".tag_type.?;770 pub const Tag = @typeInfo(Base).@"union".tag_type.?;
769 };771 };
...@@ -899,7 +901,10 @@ pub const Memory = struct {...@@ -899,7 +901,10 @@ pub const Memory = struct {
899pub const Immediate = union(enum) {901pub const Immediate = union(enum) {
900 signed: i32,902 signed: i32,
901 unsigned: u64,903 unsigned: u64,
902 reloc: SymbolOffset,904 nav: NavOffset,
905 uav: InternPool.Key.Ptr.BaseAddr.Uav,
906 lazy_sym: link.File.LazySymbol,
907 extern_func: Mir.NullTerminatedString,
903908
904 pub fn u(x: u64) Immediate {909 pub fn u(x: u64) Immediate {
905 return .{ .unsigned = x };910 return .{ .unsigned = x };
...@@ -909,10 +914,6 @@ pub const Immediate = union(enum) {...@@ -909,10 +914,6 @@ pub const Immediate = union(enum) {
909 return .{ .signed = x };914 return .{ .signed = x };
910 }915 }
911916
912 pub fn rel(sym_off: SymbolOffset) Immediate {
913 return .{ .reloc = sym_off };
914 }
915
916 pub fn format(917 pub fn format(
917 imm: Immediate,918 imm: Immediate,
918 comptime _: []const u8,919 comptime _: []const u8,
...@@ -921,7 +922,10 @@ pub const Immediate = union(enum) {...@@ -921,7 +922,10 @@ pub const Immediate = union(enum) {
921 ) @TypeOf(writer).Error!void {922 ) @TypeOf(writer).Error!void {
922 switch (imm) {923 switch (imm) {
923 inline else => |int| try writer.print("{d}", .{int}),924 inline else => |int| try writer.print("{d}", .{int}),
924 .reloc => |sym_off| try writer.print("Symbol({[sym_index]d}) + {[off]d}", sym_off),925 .nav => |nav_off| try writer.print("Nav({d}) + {d}", .{ @intFromEnum(nav_off.nav), nav_off.off }),
926 .uav => |uav| try writer.print("Uav({d})", .{@intFromEnum(uav.val)}),
927 .lazy_sym => |lazy_sym| try writer.print("LazySym({s}, {d})", .{ @tagName(lazy_sym.kind), @intFromEnum(lazy_sym.ty) }),
928 .extern_func => |extern_func| try writer.print("ExternFunc({d})", .{@intFromEnum(extern_func)}),
925 }929 }
926 }930 }
927};931};
src/arch/x86_64/encoder.zig+11-6
...@@ -138,7 +138,7 @@ pub const Instruction = struct {...@@ -138,7 +138,7 @@ pub const Instruction = struct {
138 .moffs => true,138 .moffs => true,
139 .rip => false,139 .rip => false,
140 .sib => |s| switch (s.base) {140 .sib => |s| switch (s.base) {
141 .none, .frame, .table, .reloc, .pcrel, .rip_inst => false,141 .none, .frame, .table, .rip_inst, .nav, .uav, .lazy_sym, .extern_func => false,
142 .reg => |reg| reg.isClass(.segment),142 .reg => |reg| reg.isClass(.segment),
143 },143 },
144 };144 };
...@@ -211,7 +211,7 @@ pub const Instruction = struct {...@@ -211,7 +211,7 @@ pub const Instruction = struct {
211 .none, .imm => 0b00,211 .none, .imm => 0b00,
212 .reg => |reg| @truncate(reg.enc() >> 3),212 .reg => |reg| @truncate(reg.enc() >> 3),
213 .mem => |mem| switch (mem.base()) {213 .mem => |mem| switch (mem.base()) {
214 .none, .frame, .table, .reloc, .pcrel, .rip_inst => 0b00, // rsp, rbp, and rip are not extended214 .none, .frame, .table, .rip_inst, .nav, .uav, .lazy_sym, .extern_func => 0b00, // rsp, rbp, and rip are not extended
215 .reg => |reg| @truncate(reg.enc() >> 3),215 .reg => |reg| @truncate(reg.enc() >> 3),
216 },216 },
217 .bytes => unreachable,217 .bytes => unreachable,
...@@ -281,9 +281,14 @@ pub const Instruction = struct {...@@ -281,9 +281,14 @@ pub const Instruction = struct {
281 .reg => |reg| try writer.print("{s}", .{@tagName(reg)}),281 .reg => |reg| try writer.print("{s}", .{@tagName(reg)}),
282 .frame => |frame_index| try writer.print("{}", .{frame_index}),282 .frame => |frame_index| try writer.print("{}", .{frame_index}),
283 .table => try writer.print("Table", .{}),283 .table => try writer.print("Table", .{}),
284 .reloc => |sym_index| try writer.print("Symbol({d})", .{sym_index}),
285 .pcrel => |sym_index| try writer.print("PcRelSymbol({d})", .{sym_index}),
286 .rip_inst => |inst_index| try writer.print("RipInst({d})", .{inst_index}),284 .rip_inst => |inst_index| try writer.print("RipInst({d})", .{inst_index}),
285 .nav => |nav| try writer.print("Nav({d})", .{@intFromEnum(nav)}),
286 .uav => |uav| try writer.print("Uav({d})", .{@intFromEnum(uav.val)}),
287 .lazy_sym => |lazy_sym| try writer.print("LazySym({s}, {d})", .{
288 @tagName(lazy_sym.kind),
289 @intFromEnum(lazy_sym.ty),
290 }),
291 .extern_func => |extern_func| try writer.print("ExternFunc({d})", .{@intFromEnum(extern_func)}),
287 }292 }
288 if (mem.scaleIndex()) |si| {293 if (mem.scaleIndex()) |si| {
289 if (any) try writer.writeAll(" + ");294 if (any) try writer.writeAll(" + ");
...@@ -718,11 +723,11 @@ pub const Instruction = struct {...@@ -718,11 +723,11 @@ pub const Instruction = struct {
718 try encoder.modRm_indirectDisp32(operand_enc, 0);723 try encoder.modRm_indirectDisp32(operand_enc, 0);
719 try encoder.disp32(undefined);724 try encoder.disp32(undefined);
720 } else return error.CannotEncode,725 } else return error.CannotEncode,
721 .reloc => if (@TypeOf(encoder).options.allow_symbols) {726 .nav, .uav, .lazy_sym, .extern_func => if (@TypeOf(encoder).options.allow_symbols) {
722 try encoder.modRm_indirectDisp32(operand_enc, 0);727 try encoder.modRm_indirectDisp32(operand_enc, 0);
723 try encoder.disp32(undefined);728 try encoder.disp32(undefined);
724 } else return error.CannotEncode,729 } else return error.CannotEncode,
725 .pcrel, .rip_inst => {730 .rip_inst => {
726 try encoder.modRm_RIPDisp32(operand_enc);731 try encoder.modRm_RIPDisp32(operand_enc);
727 try encoder.disp32(sib.disp);732 try encoder.disp32(sib.disp);
728 },733 },
src/codegen.zig+194-112
...@@ -85,13 +85,99 @@ pub fn legalizeFeatures(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) ?*co...@@ -85,13 +85,99 @@ pub fn legalizeFeatures(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) ?*co
85 }85 }
86}86}
8787
88/// Every code generation backend has a different MIR representation. However, we want to pass
89/// MIR from codegen to the linker *regardless* of which backend is in use. So, we use this: a
90/// union of all MIR types. The active tag is known from the backend in use; see `AnyMir.tag`.
91pub const AnyMir = union {
92 aarch64: @import("arch/aarch64/Mir.zig"),
93 arm: @import("arch/arm/Mir.zig"),
94 powerpc: noreturn, //@import("arch/powerpc/Mir.zig"),
95 riscv64: @import("arch/riscv64/Mir.zig"),
96 sparc64: @import("arch/sparc64/Mir.zig"),
97 x86_64: @import("arch/x86_64/Mir.zig"),
98 wasm: @import("arch/wasm/Mir.zig"),
99 c: @import("codegen/c.zig").Mir,
100
101 pub inline fn tag(comptime backend: std.builtin.CompilerBackend) []const u8 {
102 return switch (backend) {
103 .stage2_aarch64 => "aarch64",
104 .stage2_arm => "arm",
105 .stage2_powerpc => "powerpc",
106 .stage2_riscv64 => "riscv64",
107 .stage2_sparc64 => "sparc64",
108 .stage2_x86_64 => "x86_64",
109 .stage2_wasm => "wasm",
110 .stage2_c => "c",
111 else => unreachable,
112 };
113 }
114
115 pub fn deinit(mir: *AnyMir, zcu: *const Zcu) void {
116 const gpa = zcu.gpa;
117 const backend = target_util.zigBackend(zcu.root_mod.resolved_target.result, zcu.comp.config.use_llvm);
118 switch (backend) {
119 else => unreachable,
120 inline .stage2_aarch64,
121 .stage2_arm,
122 .stage2_powerpc,
123 .stage2_riscv64,
124 .stage2_sparc64,
125 .stage2_x86_64,
126 .stage2_wasm,
127 .stage2_c,
128 => |backend_ct| @field(mir, tag(backend_ct)).deinit(gpa),
129 }
130 }
131};
132
133/// Runs code generation for a function. This process converts the `Air` emitted by `Sema`,
134/// alongside annotated `Liveness` data, to machine code in the form of MIR (see `AnyMir`).
135///
136/// This is supposed to be a "pure" process, but some backends are currently buggy; see
137/// `Zcu.Feature.separate_thread` for details.
88pub fn generateFunction(138pub fn generateFunction(
89 lf: *link.File,139 lf: *link.File,
90 pt: Zcu.PerThread,140 pt: Zcu.PerThread,
91 src_loc: Zcu.LazySrcLoc,141 src_loc: Zcu.LazySrcLoc,
92 func_index: InternPool.Index,142 func_index: InternPool.Index,
93 air: Air,143 air: *const Air,
94 liveness: Air.Liveness,144 liveness: *const Air.Liveness,
145) CodeGenError!AnyMir {
146 const zcu = pt.zcu;
147 const func = zcu.funcInfo(func_index);
148 const target = zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result;
149 switch (target_util.zigBackend(target, false)) {
150 else => unreachable,
151 inline .stage2_aarch64,
152 .stage2_arm,
153 .stage2_powerpc,
154 .stage2_riscv64,
155 .stage2_sparc64,
156 .stage2_x86_64,
157 .stage2_wasm,
158 .stage2_c,
159 => |backend| {
160 dev.check(devFeatureForBackend(backend));
161 const CodeGen = importBackend(backend);
162 const mir = try CodeGen.generate(lf, pt, src_loc, func_index, air, liveness);
163 return @unionInit(AnyMir, AnyMir.tag(backend), mir);
164 },
165 }
166}
167
168/// Converts the MIR returned by `generateFunction` to finalized machine code to be placed in
169/// the output binary. This is called from linker implementations, and may query linker state.
170///
171/// This function is not called for the C backend, as `link.C` directly understands its MIR.
172///
173/// The `air` parameter is not supposed to exist, but some backends are currently buggy; see
174/// `Zcu.Feature.separate_thread` for details.
175pub fn emitFunction(
176 lf: *link.File,
177 pt: Zcu.PerThread,
178 src_loc: Zcu.LazySrcLoc,
179 func_index: InternPool.Index,
180 any_mir: *const AnyMir,
95 code: *std.ArrayListUnmanaged(u8),181 code: *std.ArrayListUnmanaged(u8),
96 debug_output: link.File.DebugInfoOutput,182 debug_output: link.File.DebugInfoOutput,
97) CodeGenError!void {183) CodeGenError!void {
...@@ -108,7 +194,8 @@ pub fn generateFunction(...@@ -108,7 +194,8 @@ pub fn generateFunction(
108 .stage2_x86_64,194 .stage2_x86_64,
109 => |backend| {195 => |backend| {
110 dev.check(devFeatureForBackend(backend));196 dev.check(devFeatureForBackend(backend));
111 return importBackend(backend).generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output);197 const mir = &@field(any_mir, AnyMir.tag(backend));
198 return mir.emit(lf, pt, src_loc, func_index, code, debug_output);
112 },199 },
113 }200 }
114}201}
...@@ -695,7 +782,6 @@ fn lowerUavRef(...@@ -695,7 +782,6 @@ fn lowerUavRef(
695 const comp = lf.comp;782 const comp = lf.comp;
696 const target = &comp.root_mod.resolved_target.result;783 const target = &comp.root_mod.resolved_target.result;
697 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);784 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);
698 const is_obj = comp.config.output_mode == .Obj;
699 const uav_val = uav.val;785 const uav_val = uav.val;
700 const uav_ty = Type.fromInterned(ip.typeOf(uav_val));786 const uav_ty = Type.fromInterned(ip.typeOf(uav_val));
701 const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn";787 const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn";
...@@ -715,21 +801,7 @@ fn lowerUavRef(...@@ -715,21 +801,7 @@ fn lowerUavRef(
715 dev.check(link.File.Tag.wasm.devFeature());801 dev.check(link.File.Tag.wasm.devFeature());
716 const wasm = lf.cast(.wasm).?;802 const wasm = lf.cast(.wasm).?;
717 assert(reloc_parent == .none);803 assert(reloc_parent == .none);
718 if (is_obj) {804 try wasm.addUavReloc(code.items.len, uav.val, uav.orig_ty, @intCast(offset));
719 try wasm.out_relocs.append(gpa, .{
720 .offset = @intCast(code.items.len),
721 .pointee = .{ .symbol_index = try wasm.uavSymbolIndex(uav.val) },
722 .tag = if (ptr_width_bytes == 4) .memory_addr_i32 else .memory_addr_i64,
723 .addend = @intCast(offset),
724 });
725 } else {
726 try wasm.uav_fixups.ensureUnusedCapacity(gpa, 1);
727 wasm.uav_fixups.appendAssumeCapacity(.{
728 .uavs_exe_index = try wasm.refUavExe(uav.val, uav.orig_ty),
729 .offset = @intCast(code.items.len),
730 .addend = @intCast(offset),
731 });
732 }
733 code.appendNTimesAssumeCapacity(0, ptr_width_bytes);805 code.appendNTimesAssumeCapacity(0, ptr_width_bytes);
734 return;806 return;
735 },807 },
...@@ -879,73 +951,39 @@ pub const GenResult = union(enum) {...@@ -879,73 +951,39 @@ pub const GenResult = union(enum) {
879 };951 };
880};952};
881953
882fn genNavRef(954pub fn genNavRef(
883 lf: *link.File,955 lf: *link.File,
884 pt: Zcu.PerThread,956 pt: Zcu.PerThread,
885 src_loc: Zcu.LazySrcLoc,957 src_loc: Zcu.LazySrcLoc,
886 val: Value,
887 nav_index: InternPool.Nav.Index,958 nav_index: InternPool.Nav.Index,
888 target: std.Target,959 target: std.Target,
889) CodeGenError!GenResult {960) CodeGenError!GenResult {
890 const zcu = pt.zcu;961 const zcu = pt.zcu;
891 const ip = &zcu.intern_pool;962 const ip = &zcu.intern_pool;
892 const ty = val.typeOf(zcu);
893 log.debug("genNavRef: val = {}", .{val.fmtValue(pt)});
894
895 if (!ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
896 const imm: u64 = switch (@divExact(target.ptrBitWidth(), 8)) {
897 1 => 0xaa,
898 2 => 0xaaaa,
899 4 => 0xaaaaaaaa,
900 8 => 0xaaaaaaaaaaaaaaaa,
901 else => unreachable,
902 };
903 return .{ .mcv = .{ .immediate = imm } };
904 }
905
906 const comp = lf.comp;
907 const gpa = comp.gpa;
908
909 // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?
910 if (ty.castPtrToFn(zcu)) |fn_ty| {
911 if (zcu.typeToFunc(fn_ty).?.is_generic) {
912 return .{ .mcv = .{ .immediate = fn_ty.abiAlignment(zcu).toByteUnits().? } };
913 }
914 } else if (ty.zigTypeTag(zcu) == .pointer) {
915 const elem_ty = ty.elemType2(zcu);
916 if (!elem_ty.hasRuntimeBits(zcu)) {
917 return .{ .mcv = .{ .immediate = elem_ty.abiAlignment(zcu).toByteUnits().? } };
918 }
919 }
920
921 const nav = ip.getNav(nav_index);963 const nav = ip.getNav(nav_index);
922 assert(!nav.isThreadlocal(ip));964 log.debug("genNavRef({})", .{nav.fqn.fmt(ip)});
923965
924 const lib_name, const linkage, const visibility = if (nav.getExtern(ip)) |e|966 const lib_name, const linkage, const is_threadlocal = if (nav.getExtern(ip)) |e|
925 .{ e.lib_name, e.linkage, e.visibility }967 .{ e.lib_name, e.linkage, e.is_threadlocal and zcu.comp.config.any_non_single_threaded }
926 else968 else
927 .{ .none, .internal, .default };969 .{ .none, .internal, false };
928
929 const name = nav.name;
930 if (lf.cast(.elf)) |elf_file| {970 if (lf.cast(.elf)) |elf_file| {
931 const zo = elf_file.zigObjectPtr().?;971 const zo = elf_file.zigObjectPtr().?;
932 switch (linkage) {972 switch (linkage) {
933 .internal => {973 .internal => {
934 const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index);974 const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index);
975 if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
935 return .{ .mcv = .{ .lea_symbol = sym_index } };976 return .{ .mcv = .{ .lea_symbol = sym_index } };
936 },977 },
937 .strong, .weak => {978 .strong, .weak => {
938 const sym_index = try elf_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));979 const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
939 switch (linkage) {980 switch (linkage) {
940 .internal => unreachable,981 .internal => unreachable,
941 .strong => {},982 .strong => {},
942 .weak => zo.symbol(sym_index).flags.weak = true,983 .weak => zo.symbol(sym_index).flags.weak = true,
943 .link_once => unreachable,984 .link_once => unreachable,
944 }985 }
945 switch (visibility) {986 if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
946 .default => zo.symbol(sym_index).flags.is_extern_ptr = true,
947 .hidden, .protected => {},
948 }
949 return .{ .mcv = .{ .lea_symbol = sym_index } };987 return .{ .mcv = .{ .lea_symbol = sym_index } };
950 },988 },
951 .link_once => unreachable,989 .link_once => unreachable,
...@@ -955,21 +993,18 @@ fn genNavRef(...@@ -955,21 +993,18 @@ fn genNavRef(
955 switch (linkage) {993 switch (linkage) {
956 .internal => {994 .internal => {
957 const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index);995 const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index);
958 const sym = zo.symbols.items[sym_index];996 if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
959 return .{ .mcv = .{ .lea_symbol = sym.nlist_idx } };997 return .{ .mcv = .{ .lea_symbol = sym_index } };
960 },998 },
961 .strong, .weak => {999 .strong, .weak => {
962 const sym_index = try macho_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));1000 const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
963 switch (linkage) {1001 switch (linkage) {
964 .internal => unreachable,1002 .internal => unreachable,
965 .strong => {},1003 .strong => {},
966 .weak => zo.symbols.items[sym_index].flags.weak = true,1004 .weak => zo.symbols.items[sym_index].flags.weak = true,
967 .link_once => unreachable,1005 .link_once => unreachable,
968 }1006 }
969 switch (visibility) {1007 if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
970 .default => zo.symbols.items[sym_index].flags.is_extern_ptr = true,
971 .hidden, .protected => {},
972 }
973 return .{ .mcv = .{ .lea_symbol = sym_index } };1008 return .{ .mcv = .{ .lea_symbol = sym_index } };
974 },1009 },
975 .link_once => unreachable,1010 .link_once => unreachable,
...@@ -980,12 +1015,12 @@ fn genNavRef(...@@ -980,12 +1015,12 @@ fn genNavRef(
980 .internal => {1015 .internal => {
981 const atom_index = try coff_file.getOrCreateAtomForNav(nav_index);1016 const atom_index = try coff_file.getOrCreateAtomForNav(nav_index);
982 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;1017 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
983 return .{ .mcv = .{ .load_got = sym_index } };1018 return .{ .mcv = .{ .lea_symbol = sym_index } };
984 },1019 },
985 .strong, .weak => {1020 .strong, .weak => {
986 const global_index = try coff_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));1021 const global_index = try coff_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
987 try coff_file.need_got_table.put(gpa, global_index, {}); // needs GOT1022 try coff_file.need_got_table.put(zcu.gpa, global_index, {}); // needs GOT
988 return .{ .mcv = .{ .load_got = link.File.Coff.global_symbol_bit | global_index } };1023 return .{ .mcv = .{ .lea_symbol = global_index } };
989 },1024 },
990 .link_once => unreachable,1025 .link_once => unreachable,
991 }1026 }
...@@ -994,11 +1029,12 @@ fn genNavRef(...@@ -994,11 +1029,12 @@ fn genNavRef(
994 const atom = p9.getAtom(atom_index);1029 const atom = p9.getAtom(atom_index);
995 return .{ .mcv = .{ .memory = atom.getOffsetTableAddress(p9) } };1030 return .{ .mcv = .{ .memory = atom.getOffsetTableAddress(p9) } };
996 } else {1031 } else {
997 const msg = try ErrorMsg.create(gpa, src_loc, "TODO genNavRef for target {}", .{target});1032 const msg = try ErrorMsg.create(zcu.gpa, src_loc, "TODO genNavRef for target {}", .{target});
998 return .{ .fail = msg };1033 return .{ .fail = msg };
999 }1034 }
1000}1035}
10011036
1037/// deprecated legacy code path
1002pub fn genTypedValue(1038pub fn genTypedValue(
1003 lf: *link.File,1039 lf: *link.File,
1004 pt: Zcu.PerThread,1040 pt: Zcu.PerThread,
...@@ -1006,45 +1042,96 @@ pub fn genTypedValue(...@@ -1006,45 +1042,96 @@ pub fn genTypedValue(
1006 val: Value,1042 val: Value,
1007 target: std.Target,1043 target: std.Target,
1008) CodeGenError!GenResult {1044) CodeGenError!GenResult {
1045 return switch (try lowerValue(pt, val, &target)) {
1046 .none => .{ .mcv = .none },
1047 .undef => .{ .mcv = .undef },
1048 .immediate => |imm| .{ .mcv = .{ .immediate = imm } },
1049 .lea_nav => |nav| genNavRef(lf, pt, src_loc, nav, target),
1050 .lea_uav => |uav| switch (try lf.lowerUav(
1051 pt,
1052 uav.val,
1053 Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu),
1054 src_loc,
1055 )) {
1056 .mcv => |mcv| .{ .mcv = switch (mcv) {
1057 else => unreachable,
1058 .load_direct => |sym_index| .{ .lea_direct = sym_index },
1059 .load_symbol => |sym_index| .{ .lea_symbol = sym_index },
1060 } },
1061 .fail => |em| .{ .fail = em },
1062 },
1063 .load_uav => |uav| lf.lowerUav(
1064 pt,
1065 uav.val,
1066 Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu),
1067 src_loc,
1068 ),
1069 };
1070}
1071
1072const LowerResult = union(enum) {
1073 none,
1074 undef,
1075 /// The bit-width of the immediate may be smaller than `u64`. For example, on 32-bit targets
1076 /// such as ARM, the immediate will never exceed 32-bits.
1077 immediate: u64,
1078 lea_nav: InternPool.Nav.Index,
1079 lea_uav: InternPool.Key.Ptr.BaseAddr.Uav,
1080 load_uav: InternPool.Key.Ptr.BaseAddr.Uav,
1081};
1082
1083pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allocator.Error!LowerResult {
1009 const zcu = pt.zcu;1084 const zcu = pt.zcu;
1010 const ip = &zcu.intern_pool;1085 const ip = &zcu.intern_pool;
1011 const ty = val.typeOf(zcu);1086 const ty = val.typeOf(zcu);
10121087
1013 log.debug("genTypedValue: val = {}", .{val.fmtValue(pt)});1088 log.debug("lowerValue(@as({}, {}))", .{ ty.fmt(pt), val.fmtValue(pt) });
10141089
1015 if (val.isUndef(zcu)) return .{ .mcv = .undef };1090 if (val.isUndef(zcu)) return .undef;
10161091
1017 switch (ty.zigTypeTag(zcu)) {1092 switch (ty.zigTypeTag(zcu)) {
1018 .void => return .{ .mcv = .none },1093 .void => return .none,
1019 .pointer => switch (ty.ptrSize(zcu)) {1094 .pointer => switch (ty.ptrSize(zcu)) {
1020 .slice => {},1095 .slice => {},
1021 else => switch (val.toIntern()) {1096 else => switch (val.toIntern()) {
1022 .null_value => {1097 .null_value => {
1023 return .{ .mcv = .{ .immediate = 0 } };1098 return .{ .immediate = 0 };
1024 },1099 },
1025 else => switch (ip.indexToKey(val.toIntern())) {1100 else => switch (ip.indexToKey(val.toIntern())) {
1026 .int => {1101 .int => {
1027 return .{ .mcv = .{ .immediate = val.toUnsignedInt(zcu) } };1102 return .{ .immediate = val.toUnsignedInt(zcu) };
1028 },1103 },
1029 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {1104 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
1030 .nav => |nav| return genNavRef(lf, pt, src_loc, val, nav, target),1105 .nav => |nav| {
1031 .uav => |uav| if (Value.fromInterned(uav.val).typeOf(zcu).hasRuntimeBits(zcu))1106 if (!ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
1032 return switch (try lf.lowerUav(1107 const imm: u64 = switch (@divExact(target.ptrBitWidth(), 8)) {
1033 pt,1108 1 => 0xaa,
1034 uav.val,1109 2 => 0xaaaa,
1035 Type.fromInterned(uav.orig_ty).ptrAlignment(zcu),1110 4 => 0xaaaaaaaa,
1036 src_loc,1111 8 => 0xaaaaaaaaaaaaaaaa,
1037 )) {
1038 .mcv => |mcv| return .{ .mcv = switch (mcv) {
1039 .load_direct => |sym_index| .{ .lea_direct = sym_index },
1040 .load_symbol => |sym_index| .{ .lea_symbol = sym_index },
1041 else => unreachable,1112 else => unreachable,
1042 } },1113 };
1043 .fail => |em| return .{ .fail = em },1114 return .{ .immediate = imm };
1044 }1115 }
1116
1117 if (ty.castPtrToFn(zcu)) |fn_ty| {
1118 if (zcu.typeToFunc(fn_ty).?.is_generic) {
1119 return .{ .immediate = fn_ty.abiAlignment(zcu).toByteUnits().? };
1120 }
1121 } else if (ty.zigTypeTag(zcu) == .pointer) {
1122 const elem_ty = ty.elemType2(zcu);
1123 if (!elem_ty.hasRuntimeBits(zcu)) {
1124 return .{ .immediate = elem_ty.abiAlignment(zcu).toByteUnits().? };
1125 }
1126 }
1127
1128 return .{ .lea_nav = nav };
1129 },
1130 .uav => |uav| if (Value.fromInterned(uav.val).typeOf(zcu).hasRuntimeBits(zcu))
1131 return .{ .lea_uav = uav }
1045 else1132 else
1046 return .{ .mcv = .{ .immediate = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu)1133 return .{ .immediate = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu)
1047 .forward(@intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() | 1)) / 3)) } },1134 .forward(@intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() | 1)) / 3)) },
1048 else => {},1135 else => {},
1049 },1136 },
1050 else => {},1137 else => {},
...@@ -1058,39 +1145,35 @@ pub fn genTypedValue(...@@ -1058,39 +1145,35 @@ pub fn genTypedValue(
1058 .signed => @bitCast(val.toSignedInt(zcu)),1145 .signed => @bitCast(val.toSignedInt(zcu)),
1059 .unsigned => val.toUnsignedInt(zcu),1146 .unsigned => val.toUnsignedInt(zcu),
1060 };1147 };
1061 return .{ .mcv = .{ .immediate = unsigned } };1148 return .{ .immediate = unsigned };
1062 }1149 }
1063 },1150 },
1064 .bool => {1151 .bool => {
1065 return .{ .mcv = .{ .immediate = @intFromBool(val.toBool()) } };1152 return .{ .immediate = @intFromBool(val.toBool()) };
1066 },1153 },
1067 .optional => {1154 .optional => {
1068 if (ty.isPtrLikeOptional(zcu)) {1155 if (ty.isPtrLikeOptional(zcu)) {
1069 return genTypedValue(1156 return lowerValue(
1070 lf,
1071 pt,1157 pt,
1072 src_loc,1158 val.optionalValue(zcu) orelse return .{ .immediate = 0 },
1073 val.optionalValue(zcu) orelse return .{ .mcv = .{ .immediate = 0 } },
1074 target,1159 target,
1075 );1160 );
1076 } else if (ty.abiSize(zcu) == 1) {1161 } else if (ty.abiSize(zcu) == 1) {
1077 return .{ .mcv = .{ .immediate = @intFromBool(!val.isNull(zcu)) } };1162 return .{ .immediate = @intFromBool(!val.isNull(zcu)) };
1078 }1163 }
1079 },1164 },
1080 .@"enum" => {1165 .@"enum" => {
1081 const enum_tag = ip.indexToKey(val.toIntern()).enum_tag;1166 const enum_tag = ip.indexToKey(val.toIntern()).enum_tag;
1082 return genTypedValue(1167 return lowerValue(
1083 lf,
1084 pt,1168 pt,
1085 src_loc,
1086 Value.fromInterned(enum_tag.int),1169 Value.fromInterned(enum_tag.int),
1087 target,1170 target,
1088 );1171 );
1089 },1172 },
1090 .error_set => {1173 .error_set => {
1091 const err_name = ip.indexToKey(val.toIntern()).err.name;1174 const err_name = ip.indexToKey(val.toIntern()).err.name;
1092 const error_index = try pt.getErrorValue(err_name);1175 const error_index = ip.getErrorValueIfExists(err_name).?;
1093 return .{ .mcv = .{ .immediate = error_index } };1176 return .{ .immediate = error_index };
1094 },1177 },
1095 .error_union => {1178 .error_union => {
1096 const err_type = ty.errorUnionSet(zcu);1179 const err_type = ty.errorUnionSet(zcu);
...@@ -1099,20 +1182,16 @@ pub fn genTypedValue(...@@ -1099,20 +1182,16 @@ pub fn genTypedValue(
1099 // We use the error type directly as the type.1182 // We use the error type directly as the type.
1100 const err_int_ty = try pt.errorIntType();1183 const err_int_ty = try pt.errorIntType();
1101 switch (ip.indexToKey(val.toIntern()).error_union.val) {1184 switch (ip.indexToKey(val.toIntern()).error_union.val) {
1102 .err_name => |err_name| return genTypedValue(1185 .err_name => |err_name| return lowerValue(
1103 lf,
1104 pt,1186 pt,
1105 src_loc,
1106 Value.fromInterned(try pt.intern(.{ .err = .{1187 Value.fromInterned(try pt.intern(.{ .err = .{
1107 .ty = err_type.toIntern(),1188 .ty = err_type.toIntern(),
1108 .name = err_name,1189 .name = err_name,
1109 } })),1190 } })),
1110 target,1191 target,
1111 ),1192 ),
1112 .payload => return genTypedValue(1193 .payload => return lowerValue(
1113 lf,
1114 pt,1194 pt,
1115 src_loc,
1116 try pt.intValue(err_int_ty, 0),1195 try pt.intValue(err_int_ty, 0),
1117 target,1196 target,
1118 ),1197 ),
...@@ -1132,7 +1211,10 @@ pub fn genTypedValue(...@@ -1132,7 +1211,10 @@ pub fn genTypedValue(
1132 else => {},1211 else => {},
1133 }1212 }
11341213
1135 return lf.lowerUav(pt, val.toIntern(), .none, src_loc);1214 return .{ .load_uav = .{
1215 .val = val.toIntern(),
1216 .orig_ty = (try pt.singleConstPtrType(ty)).toIntern(),
1217 } };
1136}1218}
11371219
1138pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {1220pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
src/codegen/c.zig+123-23
...@@ -3,6 +3,7 @@ const builtin = @import("builtin");...@@ -3,6 +3,7 @@ const builtin = @import("builtin");
3const assert = std.debug.assert;3const assert = std.debug.assert;
4const mem = std.mem;4const mem = std.mem;
5const log = std.log.scoped(.c);5const log = std.log.scoped(.c);
6const Allocator = mem.Allocator;
67
7const dev = @import("../dev.zig");8const dev = @import("../dev.zig");
8const link = @import("../link.zig");9const link = @import("../link.zig");
...@@ -30,6 +31,35 @@ pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {...@@ -30,6 +31,35 @@ pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
30 }) else null; // we don't currently ask zig1 to use safe optimization modes31 }) else null; // we don't currently ask zig1 to use safe optimization modes
31}32}
3233
34/// For most backends, MIR is basically a sequence of machine code instructions, perhaps with some
35/// "pseudo instructions" thrown in. For the C backend, it is instead the generated C code for a
36/// single function. We also need to track some information to get merged into the global `link.C`
37/// state, including:
38/// * The UAVs used, so declarations can be emitted in `flush`
39/// * The types used, so declarations can be emitted in `flush`
40/// * The lazy functions used, so definitions can be emitted in `flush`
41pub const Mir = struct {
42 /// This map contains all the UAVs we saw generating this function.
43 /// `link.C` will merge them into its `uavs`/`aligned_uavs` fields.
44 /// Key is the value of the UAV; value is the UAV's alignment, or
45 /// `.none` for natural alignment. The specified alignment is never
46 /// less than the natural alignment.
47 uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
48 // These remaining fields are essentially just an owned version of `link.C.AvBlock`.
49 code: []u8,
50 fwd_decl: []u8,
51 ctype_pool: CType.Pool,
52 lazy_fns: LazyFnMap,
53
54 pub fn deinit(mir: *Mir, gpa: Allocator) void {
55 mir.uavs.deinit(gpa);
56 gpa.free(mir.code);
57 gpa.free(mir.fwd_decl);
58 mir.ctype_pool.deinit(gpa);
59 mir.lazy_fns.deinit(gpa);
60 }
61};
62
33pub const CType = @import("c/Type.zig");63pub const CType = @import("c/Type.zig");
3464
35pub const CValue = union(enum) {65pub const CValue = union(enum) {
...@@ -671,7 +701,7 @@ pub const Object = struct {...@@ -671,7 +701,7 @@ pub const Object = struct {
671701
672/// This data is available both when outputting .c code and when outputting an .h file.702/// This data is available both when outputting .c code and when outputting an .h file.
673pub const DeclGen = struct {703pub const DeclGen = struct {
674 gpa: mem.Allocator,704 gpa: Allocator,
675 pt: Zcu.PerThread,705 pt: Zcu.PerThread,
676 mod: *Module,706 mod: *Module,
677 pass: Pass,707 pass: Pass,
...@@ -682,10 +712,12 @@ pub const DeclGen = struct {...@@ -682,10 +712,12 @@ pub const DeclGen = struct {
682 error_msg: ?*Zcu.ErrorMsg,712 error_msg: ?*Zcu.ErrorMsg,
683 ctype_pool: CType.Pool,713 ctype_pool: CType.Pool,
684 scratch: std.ArrayListUnmanaged(u32),714 scratch: std.ArrayListUnmanaged(u32),
685 /// Keeps track of anonymous decls that need to be rendered before this715 /// This map contains all the UAVs we saw generating this function.
686 /// (named) Decl in the output C code.716 /// `link.C` will merge them into its `uavs`/`aligned_uavs` fields.
687 uav_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.AvBlock),717 /// Key is the value of the UAV; value is the UAV's alignment, or
688 aligned_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),718 /// `.none` for natural alignment. The specified alignment is never
719 /// less than the natural alignment.
720 uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
689721
690 pub const Pass = union(enum) {722 pub const Pass = union(enum) {
691 nav: InternPool.Nav.Index,723 nav: InternPool.Nav.Index,
...@@ -753,21 +785,17 @@ pub const DeclGen = struct {...@@ -753,21 +785,17 @@ pub const DeclGen = struct {
753 // Indicate that the anon decl should be rendered to the output so that785 // Indicate that the anon decl should be rendered to the output so that
754 // our reference above is not undefined.786 // our reference above is not undefined.
755 const ptr_type = ip.indexToKey(uav.orig_ty).ptr_type;787 const ptr_type = ip.indexToKey(uav.orig_ty).ptr_type;
756 const gop = try dg.uav_deps.getOrPut(dg.gpa, uav.val);788 const gop = try dg.uavs.getOrPut(dg.gpa, uav.val);
757 if (!gop.found_existing) gop.value_ptr.* = .{};789 if (!gop.found_existing) gop.value_ptr.* = .none;
758790 // If there is an explicit alignment, greater than the current one, use it.
759 // Only insert an alignment entry if the alignment is greater than ABI791 // Note that we intentionally start at `.none`, so `gop.value_ptr.*` is never
760 // alignment. If there is already an entry, keep the greater alignment.792 // underaligned, so we don't need to worry about the `.none` case here.
761 const explicit_alignment = ptr_type.flags.alignment;793 if (ptr_type.flags.alignment != .none) {
762 if (explicit_alignment != .none) {794 // Resolve the current alignment so we can choose the bigger one.
763 const abi_alignment = Type.fromInterned(ptr_type.child).abiAlignment(zcu);795 const cur_alignment: Alignment = if (gop.value_ptr.* == .none) abi: {
764 if (explicit_alignment.order(abi_alignment).compare(.gt)) {796 break :abi Type.fromInterned(ptr_type.child).abiAlignment(zcu);
765 const aligned_gop = try dg.aligned_uavs.getOrPut(dg.gpa, uav.val);797 } else gop.value_ptr.*;
766 aligned_gop.value_ptr.* = if (aligned_gop.found_existing)798 gop.value_ptr.* = cur_alignment.maxStrict(ptr_type.flags.alignment);
767 aligned_gop.value_ptr.maxStrict(explicit_alignment)
768 else
769 explicit_alignment;
770 }
771 }799 }
772 }800 }
773801
...@@ -2895,7 +2923,79 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn...@@ -2895,7 +2923,79 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
2895 }2923 }
2896}2924}
28972925
2898pub fn genFunc(f: *Function) !void {2926pub fn generate(
2927 lf: *link.File,
2928 pt: Zcu.PerThread,
2929 src_loc: Zcu.LazySrcLoc,
2930 func_index: InternPool.Index,
2931 air: *const Air,
2932 liveness: *const Air.Liveness,
2933) @import("../codegen.zig").CodeGenError!Mir {
2934 const zcu = pt.zcu;
2935 const gpa = zcu.gpa;
2936
2937 _ = src_loc;
2938 assert(lf.tag == .c);
2939
2940 const func = zcu.funcInfo(func_index);
2941
2942 var function: Function = .{
2943 .value_map = .init(gpa),
2944 .air = air.*,
2945 .liveness = liveness.*,
2946 .func_index = func_index,
2947 .object = .{
2948 .dg = .{
2949 .gpa = gpa,
2950 .pt = pt,
2951 .mod = zcu.navFileScope(func.owner_nav).mod.?,
2952 .error_msg = null,
2953 .pass = .{ .nav = func.owner_nav },
2954 .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked,
2955 .expected_block = null,
2956 .fwd_decl = .init(gpa),
2957 .ctype_pool = .empty,
2958 .scratch = .empty,
2959 .uavs = .empty,
2960 },
2961 .code = .init(gpa),
2962 .indent_writer = undefined, // set later so we can get a pointer to object.code
2963 },
2964 .lazy_fns = .empty,
2965 };
2966 defer {
2967 function.object.code.deinit();
2968 function.object.dg.fwd_decl.deinit();
2969 function.object.dg.ctype_pool.deinit(gpa);
2970 function.object.dg.scratch.deinit(gpa);
2971 function.object.dg.uavs.deinit(gpa);
2972 function.deinit();
2973 }
2974 try function.object.dg.ctype_pool.init(gpa);
2975 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };
2976
2977 genFunc(&function) catch |err| switch (err) {
2978 error.AnalysisFail => return zcu.codegenFailMsg(func.owner_nav, function.object.dg.error_msg.?),
2979 error.OutOfMemory => |e| return e,
2980 };
2981
2982 var mir: Mir = .{
2983 .uavs = .empty,
2984 .code = &.{},
2985 .fwd_decl = &.{},
2986 .ctype_pool = .empty,
2987 .lazy_fns = .empty,
2988 };
2989 errdefer mir.deinit(gpa);
2990 mir.uavs = function.object.dg.uavs.move();
2991 mir.code = try function.object.code.toOwnedSlice();
2992 mir.fwd_decl = try function.object.dg.fwd_decl.toOwnedSlice();
2993 mir.ctype_pool = function.object.dg.ctype_pool.move();
2994 mir.lazy_fns = function.lazy_fns.move();
2995 return mir;
2996}
2997
2998fn genFunc(f: *Function) !void {
2899 const tracy = trace(@src());2999 const tracy = trace(@src());
2900 defer tracy.end();3000 defer tracy.end();
29013001
...@@ -8482,7 +8582,7 @@ fn iterateBigTomb(f: *Function, inst: Air.Inst.Index) BigTomb {...@@ -8482,7 +8582,7 @@ fn iterateBigTomb(f: *Function, inst: Air.Inst.Index) BigTomb {
84828582
8483/// A naive clone of this map would create copies of the ArrayList which is8583/// A naive clone of this map would create copies of the ArrayList which is
8484/// stored in the values. This function additionally clones the values.8584/// stored in the values. This function additionally clones the values.
8485fn cloneFreeLocalsMap(gpa: mem.Allocator, map: *LocalsMap) !LocalsMap {8585fn cloneFreeLocalsMap(gpa: Allocator, map: *LocalsMap) !LocalsMap {
8486 var cloned = try map.clone(gpa);8586 var cloned = try map.clone(gpa);
8487 const values = cloned.values();8587 const values = cloned.values();
8488 var i: usize = 0;8588 var i: usize = 0;
...@@ -8499,7 +8599,7 @@ fn cloneFreeLocalsMap(gpa: mem.Allocator, map: *LocalsMap) !LocalsMap {...@@ -8499,7 +8599,7 @@ fn cloneFreeLocalsMap(gpa: mem.Allocator, map: *LocalsMap) !LocalsMap {
8499 return cloned;8599 return cloned;
8500}8600}
85018601
8502fn deinitFreeLocalsMap(gpa: mem.Allocator, map: *LocalsMap) void {8602fn deinitFreeLocalsMap(gpa: Allocator, map: *LocalsMap) void {
8503 for (map.values()) |*value| {8603 for (map.values()) |*value| {
8504 value.deinit(gpa);8604 value.deinit(gpa);
8505 }8605 }
src/codegen/llvm.zig+41-17
...@@ -1121,8 +1121,8 @@ pub const Object = struct {...@@ -1121,8 +1121,8 @@ pub const Object = struct {
1121 o: *Object,1121 o: *Object,
1122 pt: Zcu.PerThread,1122 pt: Zcu.PerThread,
1123 func_index: InternPool.Index,1123 func_index: InternPool.Index,
1124 air: Air,1124 air: *const Air,
1125 liveness: Air.Liveness,1125 liveness: *const Air.Liveness,
1126 ) !void {1126 ) !void {
1127 assert(std.meta.eql(pt, o.pt));1127 assert(std.meta.eql(pt, o.pt));
1128 const zcu = pt.zcu;1128 const zcu = pt.zcu;
...@@ -1479,8 +1479,8 @@ pub const Object = struct {...@@ -1479,8 +1479,8 @@ pub const Object = struct {
14791479
1480 var fg: FuncGen = .{1480 var fg: FuncGen = .{
1481 .gpa = gpa,1481 .gpa = gpa,
1482 .air = air,1482 .air = air.*,
1483 .liveness = liveness,1483 .liveness = liveness.*,
1484 .ng = &ng,1484 .ng = &ng,
1485 .wip = wip,1485 .wip = wip,
1486 .is_naked = fn_info.cc == .naked,1486 .is_naked = fn_info.cc == .naked,
...@@ -1506,10 +1506,9 @@ pub const Object = struct {...@@ -1506,10 +1506,9 @@ pub const Object = struct {
1506 deinit_wip = false;1506 deinit_wip = false;
15071507
1508 fg.genBody(air.getMainBody(), .poi) catch |err| switch (err) {1508 fg.genBody(air.getMainBody(), .poi) catch |err| switch (err) {
1509 error.CodegenFail => {1509 error.CodegenFail => switch (zcu.codegenFailMsg(func.owner_nav, ng.err_msg.?)) {
1510 try zcu.failed_codegen.put(gpa, func.owner_nav, ng.err_msg.?);1510 error.CodegenFail => return,
1511 ng.err_msg = null;1511 error.OutOfMemory => |e| return e,
1512 return;
1513 },1512 },
1514 else => |e| return e,1513 else => |e| return e,
1515 };1514 };
...@@ -1561,10 +1560,9 @@ pub const Object = struct {...@@ -1561,10 +1560,9 @@ pub const Object = struct {
1561 .err_msg = null,1560 .err_msg = null,
1562 };1561 };
1563 ng.genDecl() catch |err| switch (err) {1562 ng.genDecl() catch |err| switch (err) {
1564 error.CodegenFail => {1563 error.CodegenFail => switch (pt.zcu.codegenFailMsg(nav_index, ng.err_msg.?)) {
1565 try pt.zcu.failed_codegen.put(pt.zcu.gpa, nav_index, ng.err_msg.?);1564 error.CodegenFail => return,
1566 ng.err_msg = null;1565 error.OutOfMemory => |e| return e,
1567 return;
1568 },1566 },
1569 else => |e| return e,1567 else => |e| return e,
1570 };1568 };
...@@ -1586,6 +1584,27 @@ pub const Object = struct {...@@ -1586,6 +1584,27 @@ pub const Object = struct {
1586 const global_index = self.nav_map.get(nav_index).?;1584 const global_index = self.nav_map.get(nav_index).?;
1587 const comp = zcu.comp;1585 const comp = zcu.comp;
15881586
1587 // If we're on COFF and linking with LLD, the linker cares about our exports to determine the subsystem in use.
1588 coff_export_flags: {
1589 const lf = comp.bin_file orelse break :coff_export_flags;
1590 const lld = lf.cast(.lld) orelse break :coff_export_flags;
1591 const coff = switch (lld.ofmt) {
1592 .elf, .wasm => break :coff_export_flags,
1593 .coff => |*coff| coff,
1594 };
1595 if (!ip.isFunctionType(ip.getNav(nav_index).typeOf(ip))) break :coff_export_flags;
1596 const flags = &coff.lld_export_flags;
1597 for (export_indices) |export_index| {
1598 const name = export_index.ptr(zcu).opts.name;
1599 if (name.eqlSlice("main", ip)) flags.c_main = true;
1600 if (name.eqlSlice("WinMain", ip)) flags.winmain = true;
1601 if (name.eqlSlice("wWinMain", ip)) flags.wwinmain = true;
1602 if (name.eqlSlice("WinMainCRTStartup", ip)) flags.winmain_crt_startup = true;
1603 if (name.eqlSlice("wWinMainCRTStartup", ip)) flags.wwinmain_crt_startup = true;
1604 if (name.eqlSlice("DllMainCRTStartup", ip)) flags.dllmain_crt_startup = true;
1605 }
1606 }
1607
1589 if (export_indices.len != 0) {1608 if (export_indices.len != 0) {
1590 return updateExportedGlobal(self, zcu, global_index, export_indices);1609 return updateExportedGlobal(self, zcu, global_index, export_indices);
1591 } else {1610 } else {
...@@ -9490,15 +9509,21 @@ pub const FuncGen = struct {...@@ -9490,15 +9509,21 @@ pub const FuncGen = struct {
94909509
9491 const inst_ty = self.typeOfIndex(inst);9510 const inst_ty = self.typeOfIndex(inst);
94929511
9493 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
9494 if (name == .none) return arg_val;
9495
9496 const func = zcu.funcInfo(zcu.navValue(self.ng.nav_index).toIntern());9512 const func = zcu.funcInfo(zcu.navValue(self.ng.nav_index).toIntern());
9513 const func_zir = func.zir_body_inst.resolveFull(&zcu.intern_pool).?;
9514 const file = zcu.fileByIndex(func_zir.file);
9515
9516 const mod = file.mod.?;
9517 if (mod.strip) return arg_val;
9518 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
9519 const zir = &file.zir.?;
9520 const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
9521
9497 const lbrace_line = zcu.navSrcLine(func.owner_nav) + func.lbrace_line + 1;9522 const lbrace_line = zcu.navSrcLine(func.owner_nav) + func.lbrace_line + 1;
9498 const lbrace_col = func.lbrace_column + 1;9523 const lbrace_col = func.lbrace_column + 1;
94999524
9500 const debug_parameter = try o.builder.debugParameter(9525 const debug_parameter = try o.builder.debugParameter(
9501 try o.builder.metadataString(name.toSlice(self.air)),9526 try o.builder.metadataString(name),
9502 self.file,9527 self.file,
9503 self.scope,9528 self.scope,
9504 lbrace_line,9529 lbrace_line,
...@@ -9516,7 +9541,6 @@ pub const FuncGen = struct {...@@ -9516,7 +9541,6 @@ pub const FuncGen = struct {
9516 },9541 },
9517 };9542 };
95189543
9519 const mod = self.ng.ownerModule();
9520 if (isByRef(inst_ty, zcu)) {9544 if (isByRef(inst_ty, zcu)) {
9521 _ = try self.wip.callIntrinsic(9545 _ = try self.wip.callIntrinsic(
9522 .normal,9546 .normal,
src/codegen/spirv.zig+6-5
...@@ -230,8 +230,9 @@ pub const Object = struct {...@@ -230,8 +230,9 @@ pub const Object = struct {
230 defer nav_gen.deinit();230 defer nav_gen.deinit();
231231
232 nav_gen.genNav(do_codegen) catch |err| switch (err) {232 nav_gen.genNav(do_codegen) catch |err| switch (err) {
233 error.CodegenFail => {233 error.CodegenFail => switch (zcu.codegenFailMsg(nav_index, nav_gen.error_msg.?)) {
234 try zcu.failed_codegen.put(gpa, nav_index, nav_gen.error_msg.?);234 error.CodegenFail => {},
235 error.OutOfMemory => |e| return e,
235 },236 },
236 else => |other| {237 else => |other| {
237 // There might be an error that happened *after* self.error_msg238 // There might be an error that happened *after* self.error_msg
...@@ -249,12 +250,12 @@ pub const Object = struct {...@@ -249,12 +250,12 @@ pub const Object = struct {
249 self: *Object,250 self: *Object,
250 pt: Zcu.PerThread,251 pt: Zcu.PerThread,
251 func_index: InternPool.Index,252 func_index: InternPool.Index,
252 air: Air,253 air: *const Air,
253 liveness: Air.Liveness,254 liveness: *const Air.Liveness,
254 ) !void {255 ) !void {
255 const nav = pt.zcu.funcInfo(func_index).owner_nav;256 const nav = pt.zcu.funcInfo(func_index).owner_nav;
256 // TODO: Separate types for generating decls and functions?257 // TODO: Separate types for generating decls and functions?
257 try self.genNav(pt, nav, air, liveness, true);258 try self.genNav(pt, nav, air.*, liveness.*, true);
258 }259 }
259260
260 pub fn updateNav(261 pub fn updateNav(
src/codegen/spirv/Section.zig-2
...@@ -386,8 +386,6 @@ test "SPIR-V Section emit() - string" {...@@ -386,8 +386,6 @@ test "SPIR-V Section emit() - string" {
386}386}
387387
388test "SPIR-V Section emit() - extended mask" {388test "SPIR-V Section emit() - extended mask" {
389 if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest;
390
391 var section = Section{};389 var section = Section{};
392 defer section.deinit(std.testing.allocator);390 defer section.deinit(std.testing.allocator);
393391
src/dev.zig+9
...@@ -25,6 +25,9 @@ pub const Env = enum {...@@ -25,6 +25,9 @@ pub const Env = enum {
25 /// - `zig build-* -fno-emit-bin`25 /// - `zig build-* -fno-emit-bin`
26 sema,26 sema,
2727
28 /// - `zig build-* -ofmt=c`
29 cbe,
30
28 /// - sema31 /// - sema
29 /// - `zig build-* -fincremental -fno-llvm -fno-lld -target x86_64-linux --listen=-`32 /// - `zig build-* -fincremental -fno-llvm -fno-lld -target x86_64-linux --listen=-`
30 @"x86_64-linux",33 @"x86_64-linux",
...@@ -144,6 +147,12 @@ pub const Env = enum {...@@ -144,6 +147,12 @@ pub const Env = enum {
144 => true,147 => true,
145 else => Env.ast_gen.supports(feature),148 else => Env.ast_gen.supports(feature),
146 },149 },
150 .cbe => switch (feature) {
151 .c_backend,
152 .c_linker,
153 => true,
154 else => Env.sema.supports(feature),
155 },
147 .@"x86_64-linux" => switch (feature) {156 .@"x86_64-linux" => switch (feature) {
148 .build_command,157 .build_command,
149 .stdio_listen,158 .stdio_listen,
src/libs/freebsd.zig+6-9
...@@ -985,7 +985,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {...@@ -985,7 +985,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {
985 assert(comp.freebsd_so_files == null);985 assert(comp.freebsd_so_files == null);
986 comp.freebsd_so_files = so_files;986 comp.freebsd_so_files = so_files;
987987
988 var task_buffer: [libs.len]link.Task = undefined;988 var task_buffer: [libs.len]link.PrelinkTask = undefined;
989 var task_buffer_i: usize = 0;989 var task_buffer_i: usize = 0;
990990
991 {991 {
...@@ -1004,7 +1004,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {...@@ -1004,7 +1004,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {
1004 }1004 }
1005 }1005 }
10061006
1007 comp.queueLinkTasks(task_buffer[0..task_buffer_i]);1007 comp.queuePrelinkTasks(task_buffer[0..task_buffer_i]);
1008}1008}
10091009
1010fn buildSharedLib(1010fn buildSharedLib(
...@@ -1019,10 +1019,6 @@ fn buildSharedLib(...@@ -1019,10 +1019,6 @@ fn buildSharedLib(
1019 defer tracy.end();1019 defer tracy.end();
10201020
1021 const basename = try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ lib.name, lib.sover });1021 const basename = try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ lib.name, lib.sover });
1022 const emit_bin = Compilation.EmitLoc{
1023 .directory = bin_directory,
1024 .basename = basename,
1025 };
1026 const version: Version = .{ .major = lib.sover, .minor = 0, .patch = 0 };1022 const version: Version = .{ .major = lib.sover, .minor = 0, .patch = 0 };
1027 const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?);1023 const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?);
1028 const soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else basename;1024 const soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else basename;
...@@ -1077,13 +1073,14 @@ fn buildSharedLib(...@@ -1077,13 +1073,14 @@ fn buildSharedLib(
1077 .dirs = comp.dirs.withoutLocalCache(),1073 .dirs = comp.dirs.withoutLocalCache(),
1078 .thread_pool = comp.thread_pool,1074 .thread_pool = comp.thread_pool,
1079 .self_exe_path = comp.self_exe_path,1075 .self_exe_path = comp.self_exe_path,
1080 .cache_mode = .incremental,1076 // Because we manually cache the whole set of objects, we don't cache the individual objects
1077 // within it. In fact, we *can't* do that, because we need `emit_bin` to specify the path.
1078 .cache_mode = .none,
1081 .config = config,1079 .config = config,
1082 .root_mod = root_mod,1080 .root_mod = root_mod,
1083 .root_name = lib.name,1081 .root_name = lib.name,
1084 .libc_installation = comp.libc_installation,1082 .libc_installation = comp.libc_installation,
1085 .emit_bin = emit_bin,1083 .emit_bin = .{ .yes_path = try bin_directory.join(arena, &.{basename}) },
1086 .emit_h = null,
1087 .verbose_cc = comp.verbose_cc,1084 .verbose_cc = comp.verbose_cc,
1088 .verbose_link = comp.verbose_link,1085 .verbose_link = comp.verbose_link,
1089 .verbose_air = comp.verbose_air,1086 .verbose_air = comp.verbose_air,
src/libs/glibc.zig+6-9
...@@ -1148,7 +1148,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {...@@ -1148,7 +1148,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {
1148 assert(comp.glibc_so_files == null);1148 assert(comp.glibc_so_files == null);
1149 comp.glibc_so_files = so_files;1149 comp.glibc_so_files = so_files;
11501150
1151 var task_buffer: [libs.len]link.Task = undefined;1151 var task_buffer: [libs.len]link.PrelinkTask = undefined;
1152 var task_buffer_i: usize = 0;1152 var task_buffer_i: usize = 0;
11531153
1154 {1154 {
...@@ -1170,7 +1170,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {...@@ -1170,7 +1170,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {
1170 }1170 }
1171 }1171 }
11721172
1173 comp.queueLinkTasks(task_buffer[0..task_buffer_i]);1173 comp.queuePrelinkTasks(task_buffer[0..task_buffer_i]);
1174}1174}
11751175
1176fn buildSharedLib(1176fn buildSharedLib(
...@@ -1185,10 +1185,6 @@ fn buildSharedLib(...@@ -1185,10 +1185,6 @@ fn buildSharedLib(
1185 defer tracy.end();1185 defer tracy.end();
11861186
1187 const basename = try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ lib.name, lib.sover });1187 const basename = try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ lib.name, lib.sover });
1188 const emit_bin = Compilation.EmitLoc{
1189 .directory = bin_directory,
1190 .basename = basename,
1191 };
1192 const version: Version = .{ .major = lib.sover, .minor = 0, .patch = 0 };1188 const version: Version = .{ .major = lib.sover, .minor = 0, .patch = 0 };
1193 const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?);1189 const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?);
1194 const soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else basename;1190 const soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else basename;
...@@ -1243,13 +1239,14 @@ fn buildSharedLib(...@@ -1243,13 +1239,14 @@ fn buildSharedLib(
1243 .dirs = comp.dirs.withoutLocalCache(),1239 .dirs = comp.dirs.withoutLocalCache(),
1244 .thread_pool = comp.thread_pool,1240 .thread_pool = comp.thread_pool,
1245 .self_exe_path = comp.self_exe_path,1241 .self_exe_path = comp.self_exe_path,
1246 .cache_mode = .incremental,1242 // Because we manually cache the whole set of objects, we don't cache the individual objects
1243 // within it. In fact, we *can't* do that, because we need `emit_bin` to specify the path.
1244 .cache_mode = .none,
1247 .config = config,1245 .config = config,
1248 .root_mod = root_mod,1246 .root_mod = root_mod,
1249 .root_name = lib.name,1247 .root_name = lib.name,
1250 .libc_installation = comp.libc_installation,1248 .libc_installation = comp.libc_installation,
1251 .emit_bin = emit_bin,1249 .emit_bin = .{ .yes_path = try bin_directory.join(arena, &.{basename}) },
1252 .emit_h = null,
1253 .verbose_cc = comp.verbose_cc,1250 .verbose_cc = comp.verbose_cc,
1254 .verbose_link = comp.verbose_link,1251 .verbose_link = comp.verbose_link,
1255 .verbose_air = comp.verbose_air,1252 .verbose_air = comp.verbose_air,
src/libs/libcxx.zig+4-28
...@@ -122,17 +122,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!...@@ -122,17 +122,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
122 const output_mode = .Lib;122 const output_mode = .Lib;
123 const link_mode = .static;123 const link_mode = .static;
124 const target = comp.root_mod.resolved_target.result;124 const target = comp.root_mod.resolved_target.result;
125 const basename = try std.zig.binNameAlloc(arena, .{
126 .root_name = root_name,
127 .target = target,
128 .output_mode = output_mode,
129 .link_mode = link_mode,
130 });
131
132 const emit_bin = Compilation.EmitLoc{
133 .directory = null, // Put it in the cache directory.
134 .basename = basename,
135 };
136125
137 const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" });126 const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" });
138 const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" });127 const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" });
...@@ -271,8 +260,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!...@@ -271,8 +260,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
271 .root_name = root_name,260 .root_name = root_name,
272 .thread_pool = comp.thread_pool,261 .thread_pool = comp.thread_pool,
273 .libc_installation = comp.libc_installation,262 .libc_installation = comp.libc_installation,
274 .emit_bin = emit_bin,263 .emit_bin = .yes_cache,
275 .emit_h = null,
276 .c_source_files = c_source_files.items,264 .c_source_files = c_source_files.items,
277 .verbose_cc = comp.verbose_cc,265 .verbose_cc = comp.verbose_cc,
278 .verbose_link = comp.verbose_link,266 .verbose_link = comp.verbose_link,
...@@ -308,7 +296,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!...@@ -308,7 +296,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
308 assert(comp.libcxx_static_lib == null);296 assert(comp.libcxx_static_lib == null);
309 const crt_file = try sub_compilation.toCrtFile();297 const crt_file = try sub_compilation.toCrtFile();
310 comp.libcxx_static_lib = crt_file;298 comp.libcxx_static_lib = crt_file;
311 comp.queueLinkTaskMode(crt_file.full_object_path, &config);299 comp.queuePrelinkTaskMode(crt_file.full_object_path, &config);
312}300}
313301
314pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void {302pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void {
...@@ -327,17 +315,6 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -327,17 +315,6 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
327 const output_mode = .Lib;315 const output_mode = .Lib;
328 const link_mode = .static;316 const link_mode = .static;
329 const target = comp.root_mod.resolved_target.result;317 const target = comp.root_mod.resolved_target.result;
330 const basename = try std.zig.binNameAlloc(arena, .{
331 .root_name = root_name,
332 .target = target,
333 .output_mode = output_mode,
334 .link_mode = link_mode,
335 });
336
337 const emit_bin = Compilation.EmitLoc{
338 .directory = null, // Put it in the cache directory.
339 .basename = basename,
340 };
341318
342 const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" });319 const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" });
343 const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" });320 const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" });
...@@ -467,8 +444,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -467,8 +444,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
467 .root_name = root_name,444 .root_name = root_name,
468 .thread_pool = comp.thread_pool,445 .thread_pool = comp.thread_pool,
469 .libc_installation = comp.libc_installation,446 .libc_installation = comp.libc_installation,
470 .emit_bin = emit_bin,447 .emit_bin = .yes_cache,
471 .emit_h = null,
472 .c_source_files = c_source_files.items,448 .c_source_files = c_source_files.items,
473 .verbose_cc = comp.verbose_cc,449 .verbose_cc = comp.verbose_cc,
474 .verbose_link = comp.verbose_link,450 .verbose_link = comp.verbose_link,
...@@ -504,7 +480,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -504,7 +480,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
504 assert(comp.libcxxabi_static_lib == null);480 assert(comp.libcxxabi_static_lib == null);
505 const crt_file = try sub_compilation.toCrtFile();481 const crt_file = try sub_compilation.toCrtFile();
506 comp.libcxxabi_static_lib = crt_file;482 comp.libcxxabi_static_lib = crt_file;
507 comp.queueLinkTaskMode(crt_file.full_object_path, &config);483 comp.queuePrelinkTaskMode(crt_file.full_object_path, &config);
508}484}
509485
510pub fn addCxxArgs(486pub fn addCxxArgs(
src/libs/libtsan.zig+2-8
...@@ -45,11 +45,6 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo...@@ -45,11 +45,6 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
45 .link_mode = link_mode,45 .link_mode = link_mode,
46 });46 });
4747
48 const emit_bin = Compilation.EmitLoc{
49 .directory = null, // Put it in the cache directory.
50 .basename = basename,
51 };
52
53 const optimize_mode = comp.compilerRtOptMode();48 const optimize_mode = comp.compilerRtOptMode();
54 const strip = comp.compilerRtStrip();49 const strip = comp.compilerRtStrip();
55 const unwind_tables: std.builtin.UnwindTables =50 const unwind_tables: std.builtin.UnwindTables =
...@@ -287,8 +282,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo...@@ -287,8 +282,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
287 .root_mod = root_mod,282 .root_mod = root_mod,
288 .root_name = root_name,283 .root_name = root_name,
289 .libc_installation = comp.libc_installation,284 .libc_installation = comp.libc_installation,
290 .emit_bin = emit_bin,285 .emit_bin = .yes_cache,
291 .emit_h = null,
292 .c_source_files = c_source_files.items,286 .c_source_files = c_source_files.items,
293 .verbose_cc = comp.verbose_cc,287 .verbose_cc = comp.verbose_cc,
294 .verbose_link = comp.verbose_link,288 .verbose_link = comp.verbose_link,
...@@ -325,7 +319,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo...@@ -325,7 +319,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
325 };319 };
326320
327 const crt_file = try sub_compilation.toCrtFile();321 const crt_file = try sub_compilation.toCrtFile();
328 comp.queueLinkTaskMode(crt_file.full_object_path, &config);322 comp.queuePrelinkTaskMode(crt_file.full_object_path, &config);
329 assert(comp.tsan_lib == null);323 assert(comp.tsan_lib == null);
330 comp.tsan_lib = crt_file;324 comp.tsan_lib = crt_file;
331}325}
src/libs/libunwind.zig+3-14
...@@ -31,7 +31,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -31,7 +31,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
31 const unwind_tables: std.builtin.UnwindTables =31 const unwind_tables: std.builtin.UnwindTables =
32 if (target.cpu.arch == .x86 and target.os.tag == .windows) .none else .@"async";32 if (target.cpu.arch == .x86 and target.os.tag == .windows) .none else .@"async";
33 const config = Compilation.Config.resolve(.{33 const config = Compilation.Config.resolve(.{
34 .output_mode = .Lib,34 .output_mode = output_mode,
35 .resolved_target = comp.root_mod.resolved_target,35 .resolved_target = comp.root_mod.resolved_target,
36 .is_test = false,36 .is_test = false,
37 .have_zcu = false,37 .have_zcu = false,
...@@ -85,17 +85,6 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -85,17 +85,6 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
85 };85 };
8686
87 const root_name = "unwind";87 const root_name = "unwind";
88 const link_mode = .static;
89 const basename = try std.zig.binNameAlloc(arena, .{
90 .root_name = root_name,
91 .target = target,
92 .output_mode = output_mode,
93 .link_mode = link_mode,
94 });
95 const emit_bin = Compilation.EmitLoc{
96 .directory = null, // Put it in the cache directory.
97 .basename = basename,
98 };
99 var c_source_files: [unwind_src_list.len]Compilation.CSourceFile = undefined;88 var c_source_files: [unwind_src_list.len]Compilation.CSourceFile = undefined;
100 for (unwind_src_list, 0..) |unwind_src, i| {89 for (unwind_src_list, 0..) |unwind_src, i| {
101 var cflags = std.ArrayList([]const u8).init(arena);90 var cflags = std.ArrayList([]const u8).init(arena);
...@@ -160,7 +149,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -160,7 +149,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
160 .main_mod = null,149 .main_mod = null,
161 .thread_pool = comp.thread_pool,150 .thread_pool = comp.thread_pool,
162 .libc_installation = comp.libc_installation,151 .libc_installation = comp.libc_installation,
163 .emit_bin = emit_bin,152 .emit_bin = .yes_cache,
164 .function_sections = comp.function_sections,153 .function_sections = comp.function_sections,
165 .c_source_files = &c_source_files,154 .c_source_files = &c_source_files,
166 .verbose_cc = comp.verbose_cc,155 .verbose_cc = comp.verbose_cc,
...@@ -195,7 +184,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -195,7 +184,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
195 };184 };
196185
197 const crt_file = try sub_compilation.toCrtFile();186 const crt_file = try sub_compilation.toCrtFile();
198 comp.queueLinkTaskMode(crt_file.full_object_path, &config);187 comp.queuePrelinkTaskMode(crt_file.full_object_path, &config);
199 assert(comp.libunwind_static_lib == null);188 assert(comp.libunwind_static_lib == null);
200 comp.libunwind_static_lib = crt_file;189 comp.libunwind_static_lib = crt_file;
201}190}
src/libs/musl.zig+2-3
...@@ -252,8 +252,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro...@@ -252,8 +252,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
252 .thread_pool = comp.thread_pool,252 .thread_pool = comp.thread_pool,
253 .root_name = "c",253 .root_name = "c",
254 .libc_installation = comp.libc_installation,254 .libc_installation = comp.libc_installation,
255 .emit_bin = .{ .directory = null, .basename = "libc.so" },255 .emit_bin = .yes_cache,
256 .emit_h = null,
257 .verbose_cc = comp.verbose_cc,256 .verbose_cc = comp.verbose_cc,
258 .verbose_link = comp.verbose_link,257 .verbose_link = comp.verbose_link,
259 .verbose_air = comp.verbose_air,258 .verbose_air = comp.verbose_air,
...@@ -278,7 +277,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro...@@ -278,7 +277,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
278 errdefer comp.gpa.free(basename);277 errdefer comp.gpa.free(basename);
279278
280 const crt_file = try sub_compilation.toCrtFile();279 const crt_file = try sub_compilation.toCrtFile();
281 comp.queueLinkTaskMode(crt_file.full_object_path, &config);280 comp.queuePrelinkTaskMode(crt_file.full_object_path, &config);
282 {281 {
283 comp.mutex.lock();282 comp.mutex.lock();
284 defer comp.mutex.unlock();283 defer comp.mutex.unlock();
src/libs/netbsd.zig+6-9
...@@ -650,7 +650,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {...@@ -650,7 +650,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {
650 assert(comp.netbsd_so_files == null);650 assert(comp.netbsd_so_files == null);
651 comp.netbsd_so_files = so_files;651 comp.netbsd_so_files = so_files;
652652
653 var task_buffer: [libs.len]link.Task = undefined;653 var task_buffer: [libs.len]link.PrelinkTask = undefined;
654 var task_buffer_i: usize = 0;654 var task_buffer_i: usize = 0;
655655
656 {656 {
...@@ -669,7 +669,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {...@@ -669,7 +669,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {
669 }669 }
670 }670 }
671671
672 comp.queueLinkTasks(task_buffer[0..task_buffer_i]);672 comp.queuePrelinkTasks(task_buffer[0..task_buffer_i]);
673}673}
674674
675fn buildSharedLib(675fn buildSharedLib(
...@@ -684,10 +684,6 @@ fn buildSharedLib(...@@ -684,10 +684,6 @@ fn buildSharedLib(
684 defer tracy.end();684 defer tracy.end();
685685
686 const basename = try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ lib.name, lib.sover });686 const basename = try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ lib.name, lib.sover });
687 const emit_bin = Compilation.EmitLoc{
688 .directory = bin_directory,
689 .basename = basename,
690 };
691 const version: Version = .{ .major = lib.sover, .minor = 0, .patch = 0 };687 const version: Version = .{ .major = lib.sover, .minor = 0, .patch = 0 };
692 const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?);688 const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?);
693 const soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else basename;689 const soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else basename;
...@@ -741,13 +737,14 @@ fn buildSharedLib(...@@ -741,13 +737,14 @@ fn buildSharedLib(
741 .dirs = comp.dirs.withoutLocalCache(),737 .dirs = comp.dirs.withoutLocalCache(),
742 .thread_pool = comp.thread_pool,738 .thread_pool = comp.thread_pool,
743 .self_exe_path = comp.self_exe_path,739 .self_exe_path = comp.self_exe_path,
744 .cache_mode = .incremental,740 // Because we manually cache the whole set of objects, we don't cache the individual objects
741 // within it. In fact, we *can't* do that, because we need `emit_bin` to specify the path.
742 .cache_mode = .none,
745 .config = config,743 .config = config,
746 .root_mod = root_mod,744 .root_mod = root_mod,
747 .root_name = lib.name,745 .root_name = lib.name,
748 .libc_installation = comp.libc_installation,746 .libc_installation = comp.libc_installation,
749 .emit_bin = emit_bin,747 .emit_bin = .{ .yes_path = try bin_directory.join(arena, &.{basename}) },
750 .emit_h = null,
751 .verbose_cc = comp.verbose_cc,748 .verbose_cc = comp.verbose_cc,
752 .verbose_link = comp.verbose_link,749 .verbose_link = comp.verbose_link,
753 .verbose_air = comp.verbose_air,750 .verbose_air = comp.verbose_air,
src/link.zig+233-447
...@@ -8,7 +8,6 @@ const log = std.log.scoped(.link);...@@ -8,7 +8,6 @@ const log = std.log.scoped(.link);
8const trace = @import("tracy.zig").trace;8const trace = @import("tracy.zig").trace;
9const wasi_libc = @import("libs/wasi_libc.zig");9const wasi_libc = @import("libs/wasi_libc.zig");
1010
11const Air = @import("Air.zig");
12const Allocator = std.mem.Allocator;11const Allocator = std.mem.Allocator;
13const Cache = std.Build.Cache;12const Cache = std.Build.Cache;
14const Path = std.Build.Cache.Path;13const Path = std.Build.Cache.Path;
...@@ -19,15 +18,13 @@ const Zcu = @import("Zcu.zig");...@@ -19,15 +18,13 @@ const Zcu = @import("Zcu.zig");
19const InternPool = @import("InternPool.zig");18const InternPool = @import("InternPool.zig");
20const Type = @import("Type.zig");19const Type = @import("Type.zig");
21const Value = @import("Value.zig");20const Value = @import("Value.zig");
22const LlvmObject = @import("codegen/llvm.zig").Object;
23const lldMain = @import("main.zig").lldMain;
24const Package = @import("Package.zig");21const Package = @import("Package.zig");
25const dev = @import("dev.zig");22const dev = @import("dev.zig");
26const ThreadSafeQueue = @import("ThreadSafeQueue.zig").ThreadSafeQueue;
27const target_util = @import("target.zig");23const target_util = @import("target.zig");
28const codegen = @import("codegen.zig");24const codegen = @import("codegen.zig");
2925
30pub const LdScript = @import("link/LdScript.zig");26pub const LdScript = @import("link/LdScript.zig");
27pub const Queue = @import("link/Queue.zig");
3128
32pub const Diags = struct {29pub const Diags = struct {
33 /// Stored here so that function definitions can distinguish between30 /// Stored here so that function definitions can distinguish between
...@@ -386,10 +383,11 @@ pub const File = struct {...@@ -386,10 +383,11 @@ pub const File = struct {
386 emit: Path,383 emit: Path,
387384
388 file: ?fs.File,385 file: ?fs.File,
389 /// When linking with LLD, this linker code will output an object file only at386 /// When using the LLVM backend, the emitted object is written to a file with this name. This
390 /// this location, and then this path can be placed on the LLD linker line.387 /// object file then becomes a normal link input to LLD or a self-hosted linker.
391 zcu_object_sub_path: ?[]const u8 = null,388 ///
392 disable_lld_caching: bool,389 /// To convert this to an actual path, see `Compilation.resolveEmitPath` (with `kind == .temp`).
390 zcu_object_basename: ?[]const u8 = null,
393 gc_sections: bool,391 gc_sections: bool,
394 print_gc_sections: bool,392 print_gc_sections: bool,
395 build_id: std.zig.BuildId,393 build_id: std.zig.BuildId,
...@@ -425,7 +423,7 @@ pub const File = struct {...@@ -425,7 +423,7 @@ pub const File = struct {
425 tsaware: bool,423 tsaware: bool,
426 nxcompat: bool,424 nxcompat: bool,
427 dynamicbase: bool,425 dynamicbase: bool,
428 compress_debug_sections: Elf.CompressDebugSections,426 compress_debug_sections: Lld.Elf.CompressDebugSections,
429 bind_global_refs_locally: bool,427 bind_global_refs_locally: bool,
430 import_symbols: bool,428 import_symbols: bool,
431 import_table: bool,429 import_table: bool,
...@@ -436,9 +434,8 @@ pub const File = struct {...@@ -436,9 +434,8 @@ pub const File = struct {
436 export_symbol_names: []const []const u8,434 export_symbol_names: []const []const u8,
437 global_base: ?u64,435 global_base: ?u64,
438 build_id: std.zig.BuildId,436 build_id: std.zig.BuildId,
439 disable_lld_caching: bool,437 hash_style: Lld.Elf.HashStyle,
440 hash_style: Elf.HashStyle,438 sort_section: ?Lld.Elf.SortSection,
441 sort_section: ?Elf.SortSection,
442 major_subsystem_version: ?u16,439 major_subsystem_version: ?u16,
443 minor_subsystem_version: ?u16,440 minor_subsystem_version: ?u16,
444 gc_sections: ?bool,441 gc_sections: ?bool,
...@@ -522,12 +519,20 @@ pub const File = struct {...@@ -522,12 +519,20 @@ pub const File = struct {
522 emit: Path,519 emit: Path,
523 options: OpenOptions,520 options: OpenOptions,
524 ) !*File {521 ) !*File {
522 if (comp.config.use_lld) {
523 dev.check(.lld_linker);
524 assert(comp.zcu == null or comp.config.use_llvm);
525 // LLD does not support incremental linking.
526 const lld: *Lld = try .createEmpty(arena, comp, emit, options);
527 return &lld.base;
528 }
525 switch (Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt)) {529 switch (Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt)) {
526 inline else => |tag| {530 inline else => |tag| {
527 dev.check(tag.devFeature());531 dev.check(tag.devFeature());
528 const ptr = try tag.Type().open(arena, comp, emit, options);532 const ptr = try tag.Type().open(arena, comp, emit, options);
529 return &ptr.base;533 return &ptr.base;
530 },534 },
535 .lld => unreachable, // not known from ofmt
531 }536 }
532 }537 }
533538
...@@ -537,12 +542,19 @@ pub const File = struct {...@@ -537,12 +542,19 @@ pub const File = struct {
537 emit: Path,542 emit: Path,
538 options: OpenOptions,543 options: OpenOptions,
539 ) !*File {544 ) !*File {
545 if (comp.config.use_lld) {
546 dev.check(.lld_linker);
547 assert(comp.zcu == null or comp.config.use_llvm);
548 const lld: *Lld = try .createEmpty(arena, comp, emit, options);
549 return &lld.base;
550 }
540 switch (Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt)) {551 switch (Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt)) {
541 inline else => |tag| {552 inline else => |tag| {
542 dev.check(tag.devFeature());553 dev.check(tag.devFeature());
543 const ptr = try tag.Type().createEmpty(arena, comp, emit, options);554 const ptr = try tag.Type().createEmpty(arena, comp, emit, options);
544 return &ptr.base;555 return &ptr.base;
545 },556 },
557 .lld => unreachable, // not known from ofmt
546 }558 }
547 }559 }
548560
...@@ -555,6 +567,7 @@ pub const File = struct {...@@ -555,6 +567,7 @@ pub const File = struct {
555 const comp = base.comp;567 const comp = base.comp;
556 const gpa = comp.gpa;568 const gpa = comp.gpa;
557 switch (base.tag) {569 switch (base.tag) {
570 .lld => assert(base.file == null),
558 .coff, .elf, .macho, .plan9, .wasm, .goff, .xcoff => {571 .coff, .elf, .macho, .plan9, .wasm, .goff, .xcoff => {
559 if (base.file != null) return;572 if (base.file != null) return;
560 dev.checkAny(&.{ .coff_linker, .elf_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker });573 dev.checkAny(&.{ .coff_linker, .elf_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker });
...@@ -587,13 +600,12 @@ pub const File = struct {...@@ -587,13 +600,12 @@ pub const File = struct {
587 }600 }
588 }601 }
589 }602 }
590 const use_lld = build_options.have_llvm and comp.config.use_lld;
591 const output_mode = comp.config.output_mode;603 const output_mode = comp.config.output_mode;
592 const link_mode = comp.config.link_mode;604 const link_mode = comp.config.link_mode;
593 base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{605 base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{
594 .truncate = false,606 .truncate = false,
595 .read = true,607 .read = true,
596 .mode = determineMode(use_lld, output_mode, link_mode),608 .mode = determineMode(output_mode, link_mode),
597 });609 });
598 },610 },
599 .c, .spirv => dev.checkAny(&.{ .c_linker, .spirv_linker }),611 .c, .spirv => dev.checkAny(&.{ .c_linker, .spirv_linker }),
...@@ -619,7 +631,6 @@ pub const File = struct {...@@ -619,7 +631,6 @@ pub const File = struct {
619 const comp = base.comp;631 const comp = base.comp;
620 const output_mode = comp.config.output_mode;632 const output_mode = comp.config.output_mode;
621 const link_mode = comp.config.link_mode;633 const link_mode = comp.config.link_mode;
622 const use_lld = build_options.have_llvm and comp.config.use_lld;
623634
624 switch (output_mode) {635 switch (output_mode) {
625 .Obj => return,636 .Obj => return,
...@@ -630,13 +641,9 @@ pub const File = struct {...@@ -630,13 +641,9 @@ pub const File = struct {
630 .Exe => {},641 .Exe => {},
631 }642 }
632 switch (base.tag) {643 switch (base.tag) {
644 .lld => assert(base.file == null),
633 .elf => if (base.file) |f| {645 .elf => if (base.file) |f| {
634 dev.check(.elf_linker);646 dev.check(.elf_linker);
635 if (base.zcu_object_sub_path != null and use_lld) {
636 // The file we have open is not the final file that we want to
637 // make executable, so we don't have to close it.
638 return;
639 }
640 f.close();647 f.close();
641 base.file = null;648 base.file = null;
642649
...@@ -651,11 +658,6 @@ pub const File = struct {...@@ -651,11 +658,6 @@ pub const File = struct {
651 },658 },
652 .coff, .macho, .plan9, .wasm, .goff, .xcoff => if (base.file) |f| {659 .coff, .macho, .plan9, .wasm, .goff, .xcoff => if (base.file) |f| {
653 dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker });660 dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker });
654 if (base.zcu_object_sub_path != null) {
655 // The file we have open is not the final file that we want to
656 // make executable, so we don't have to close it.
657 return;
658 }
659 f.close();661 f.close();
660 base.file = null;662 base.file = null;
661663
...@@ -693,6 +695,7 @@ pub const File = struct {...@@ -693,6 +695,7 @@ pub const File = struct {
693 pub fn getGlobalSymbol(base: *File, name: []const u8, lib_name: ?[]const u8) UpdateNavError!u32 {695 pub fn getGlobalSymbol(base: *File, name: []const u8, lib_name: ?[]const u8) UpdateNavError!u32 {
694 log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name });696 log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name });
695 switch (base.tag) {697 switch (base.tag) {
698 .lld => unreachable,
696 .plan9 => unreachable,699 .plan9 => unreachable,
697 .spirv => unreachable,700 .spirv => unreachable,
698 .c => unreachable,701 .c => unreachable,
...@@ -704,10 +707,13 @@ pub const File = struct {...@@ -704,10 +707,13 @@ pub const File = struct {
704 }707 }
705708
706 /// May be called before or after updateExports for any given Nav.709 /// May be called before or after updateExports for any given Nav.
707 pub fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) UpdateNavError!void {710 /// Asserts that the ZCU is not using the LLVM backend.
711 fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) UpdateNavError!void {
712 assert(base.comp.zcu.?.llvm_object == null);
708 const nav = pt.zcu.intern_pool.getNav(nav_index);713 const nav = pt.zcu.intern_pool.getNav(nav_index);
709 assert(nav.status == .fully_resolved);714 assert(nav.status == .fully_resolved);
710 switch (base.tag) {715 switch (base.tag) {
716 .lld => unreachable,
711 inline else => |tag| {717 inline else => |tag| {
712 dev.check(tag.devFeature());718 dev.check(tag.devFeature());
713 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateNav(pt, nav_index);719 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateNav(pt, nav_index);
...@@ -721,8 +727,11 @@ pub const File = struct {...@@ -721,8 +727,11 @@ pub const File = struct {
721 TypeFailureReported,727 TypeFailureReported,
722 };728 };
723729
724 pub fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateContainerTypeError!void {730 /// Never called when LLVM is codegenning the ZCU.
731 fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateContainerTypeError!void {
732 assert(base.comp.zcu.?.llvm_object == null);
725 switch (base.tag) {733 switch (base.tag) {
734 .lld => unreachable,
726 else => {},735 else => {},
727 inline .elf => |tag| {736 inline .elf => |tag| {
728 dev.check(tag.devFeature());737 dev.check(tag.devFeature());
...@@ -732,17 +741,24 @@ pub const File = struct {...@@ -732,17 +741,24 @@ pub const File = struct {
732 }741 }
733742
734 /// May be called before or after updateExports for any given Decl.743 /// May be called before or after updateExports for any given Decl.
735 pub fn updateFunc(744 /// The active tag of `mir` is determined by the backend used for the module this function is in.
745 /// Never called when LLVM is codegenning the ZCU.
746 fn updateFunc(
736 base: *File,747 base: *File,
737 pt: Zcu.PerThread,748 pt: Zcu.PerThread,
738 func_index: InternPool.Index,749 func_index: InternPool.Index,
739 air: Air,750 /// This is owned by the caller, but the callee is permitted to mutate it provided
740 liveness: Air.Liveness,751 /// that `mir.deinit` remains legal for the caller. For instance, the callee can
752 /// take ownership of an embedded slice and replace it with `&.{}` in `mir`.
753 mir: *codegen.AnyMir,
741 ) UpdateNavError!void {754 ) UpdateNavError!void {
755 assert(base.comp.zcu.?.llvm_object == null);
742 switch (base.tag) {756 switch (base.tag) {
757 .lld => unreachable,
758 .spirv => unreachable, // see corresponding special case in `Zcu.PerThread.runCodegenInner`
743 inline else => |tag| {759 inline else => |tag| {
744 dev.check(tag.devFeature());760 dev.check(tag.devFeature());
745 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(pt, func_index, air, liveness);761 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(pt, func_index, mir);
746 },762 },
747 }763 }
748 }764 }
...@@ -755,7 +771,9 @@ pub const File = struct {...@@ -755,7 +771,9 @@ pub const File = struct {
755771
756 /// On an incremental update, fixup the line number of all `Nav`s at the given `TrackedInst`, because772 /// On an incremental update, fixup the line number of all `Nav`s at the given `TrackedInst`, because
757 /// its line number has changed. The ZIR instruction `ti_id` has tag `.declaration`.773 /// its line number has changed. The ZIR instruction `ti_id` has tag `.declaration`.
758 pub fn updateLineNumber(base: *File, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) UpdateLineNumberError!void {774 /// Never called when LLVM is codegenning the ZCU.
775 fn updateLineNumber(base: *File, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) UpdateLineNumberError!void {
776 assert(base.comp.zcu.?.llvm_object == null);
759 {777 {
760 const ti = ti_id.resolveFull(&pt.zcu.intern_pool).?;778 const ti = ti_id.resolveFull(&pt.zcu.intern_pool).?;
761 const file = pt.zcu.fileByIndex(ti.file);779 const file = pt.zcu.fileByIndex(ti.file);
...@@ -764,6 +782,7 @@ pub const File = struct {...@@ -764,6 +782,7 @@ pub const File = struct {
764 }782 }
765783
766 switch (base.tag) {784 switch (base.tag) {
785 .lld => unreachable,
767 .spirv => {},786 .spirv => {},
768 .goff, .xcoff => {},787 .goff, .xcoff => {},
769 inline else => |tag| {788 inline else => |tag| {
...@@ -803,8 +822,7 @@ pub const File = struct {...@@ -803,8 +822,7 @@ pub const File = struct {
803 OutOfMemory,822 OutOfMemory,
804 };823 };
805824
806 /// Commit pending changes and write headers. Takes into account final output mode825 /// Commit pending changes and write headers. Takes into account final output mode.
807 /// and `use_lld`, not only `effectiveOutputMode`.
808 /// `arena` has the lifetime of the call to `Compilation.update`.826 /// `arena` has the lifetime of the call to `Compilation.update`.
809 pub fn flush(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void {827 pub fn flush(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void {
810 const comp = base.comp;828 const comp = base.comp;
...@@ -826,15 +844,7 @@ pub const File = struct {...@@ -826,15 +844,7 @@ pub const File = struct {
826 };844 };
827 return;845 return;
828 }846 }
829
830 assert(base.post_prelink);847 assert(base.post_prelink);
831
832 const use_lld = build_options.have_llvm and comp.config.use_lld;
833 const output_mode = comp.config.output_mode;
834 const link_mode = comp.config.link_mode;
835 if (use_lld and output_mode == .Lib and link_mode == .static) {
836 return base.linkAsArchive(arena, tid, prog_node);
837 }
838 switch (base.tag) {848 switch (base.tag) {
839 inline else => |tag| {849 inline else => |tag| {
840 dev.check(tag.devFeature());850 dev.check(tag.devFeature());
...@@ -843,17 +853,6 @@ pub const File = struct {...@@ -843,17 +853,6 @@ pub const File = struct {
843 }853 }
844 }854 }
845855
846 /// Commit pending changes and write headers. Works based on `effectiveOutputMode`
847 /// rather than final output mode.
848 pub fn flushModule(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void {
849 switch (base.tag) {
850 inline else => |tag| {
851 dev.check(tag.devFeature());
852 return @as(*tag.Type(), @fieldParentPtr("base", base)).flushModule(arena, tid, prog_node);
853 },
854 }
855 }
856
857 pub const UpdateExportsError = error{856 pub const UpdateExportsError = error{
858 OutOfMemory,857 OutOfMemory,
859 AnalysisFail,858 AnalysisFail,
...@@ -863,13 +862,16 @@ pub const File = struct {...@@ -863,13 +862,16 @@ pub const File = struct {
863 /// a list of size 1, meaning that `exported` is exported once. However, it is possible862 /// a list of size 1, meaning that `exported` is exported once. However, it is possible
864 /// to export the same thing with multiple different symbol names (aliases).863 /// to export the same thing with multiple different symbol names (aliases).
865 /// May be called before or after updateDecl for any given Decl.864 /// May be called before or after updateDecl for any given Decl.
865 /// Never called when LLVM is codegenning the ZCU.
866 pub fn updateExports(866 pub fn updateExports(
867 base: *File,867 base: *File,
868 pt: Zcu.PerThread,868 pt: Zcu.PerThread,
869 exported: Zcu.Exported,869 exported: Zcu.Exported,
870 export_indices: []const Zcu.Export.Index,870 export_indices: []const Zcu.Export.Index,
871 ) UpdateExportsError!void {871 ) UpdateExportsError!void {
872 assert(base.comp.zcu.?.llvm_object == null);
872 switch (base.tag) {873 switch (base.tag) {
874 .lld => unreachable,
873 inline else => |tag| {875 inline else => |tag| {
874 dev.check(tag.devFeature());876 dev.check(tag.devFeature());
875 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateExports(pt, exported, export_indices);877 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateExports(pt, exported, export_indices);
...@@ -895,8 +897,11 @@ pub const File = struct {...@@ -895,8 +897,11 @@ pub const File = struct {
895 /// `Nav`'s address was not yet resolved, or the containing atom gets moved in virtual memory.897 /// `Nav`'s address was not yet resolved, or the containing atom gets moved in virtual memory.
896 /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate898 /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate
897 /// the block/atom.899 /// the block/atom.
900 /// Never called when LLVM is codegenning the ZCU.
898 pub fn getNavVAddr(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: RelocInfo) !u64 {901 pub fn getNavVAddr(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: RelocInfo) !u64 {
902 assert(base.comp.zcu.?.llvm_object == null);
899 switch (base.tag) {903 switch (base.tag) {
904 .lld => unreachable,
900 .c => unreachable,905 .c => unreachable,
901 .spirv => unreachable,906 .spirv => unreachable,
902 .wasm => unreachable,907 .wasm => unreachable,
...@@ -908,6 +913,7 @@ pub const File = struct {...@@ -908,6 +913,7 @@ pub const File = struct {
908 }913 }
909 }914 }
910915
916 /// Never called when LLVM is codegenning the ZCU.
911 pub fn lowerUav(917 pub fn lowerUav(
912 base: *File,918 base: *File,
913 pt: Zcu.PerThread,919 pt: Zcu.PerThread,
...@@ -915,7 +921,9 @@ pub const File = struct {...@@ -915,7 +921,9 @@ pub const File = struct {
915 decl_align: InternPool.Alignment,921 decl_align: InternPool.Alignment,
916 src_loc: Zcu.LazySrcLoc,922 src_loc: Zcu.LazySrcLoc,
917 ) !codegen.GenResult {923 ) !codegen.GenResult {
924 assert(base.comp.zcu.?.llvm_object == null);
918 switch (base.tag) {925 switch (base.tag) {
926 .lld => unreachable,
919 .c => unreachable,927 .c => unreachable,
920 .spirv => unreachable,928 .spirv => unreachable,
921 .wasm => unreachable,929 .wasm => unreachable,
...@@ -927,8 +935,11 @@ pub const File = struct {...@@ -927,8 +935,11 @@ pub const File = struct {
927 }935 }
928 }936 }
929937
938 /// Never called when LLVM is codegenning the ZCU.
930 pub fn getUavVAddr(base: *File, decl_val: InternPool.Index, reloc_info: RelocInfo) !u64 {939 pub fn getUavVAddr(base: *File, decl_val: InternPool.Index, reloc_info: RelocInfo) !u64 {
940 assert(base.comp.zcu.?.llvm_object == null);
931 switch (base.tag) {941 switch (base.tag) {
942 .lld => unreachable,
932 .c => unreachable,943 .c => unreachable,
933 .spirv => unreachable,944 .spirv => unreachable,
934 .wasm => unreachable,945 .wasm => unreachable,
...@@ -940,12 +951,16 @@ pub const File = struct {...@@ -940,12 +951,16 @@ pub const File = struct {
940 }951 }
941 }952 }
942953
954 /// Never called when LLVM is codegenning the ZCU.
943 pub fn deleteExport(955 pub fn deleteExport(
944 base: *File,956 base: *File,
945 exported: Zcu.Exported,957 exported: Zcu.Exported,
946 name: InternPool.NullTerminatedString,958 name: InternPool.NullTerminatedString,
947 ) void {959 ) void {
960 assert(base.comp.zcu.?.llvm_object == null);
948 switch (base.tag) {961 switch (base.tag) {
962 .lld => unreachable,
963
949 .plan9,964 .plan9,
950 .spirv,965 .spirv,
951 .goff,966 .goff,
...@@ -961,6 +976,7 @@ pub const File = struct {...@@ -961,6 +976,7 @@ pub const File = struct {
961976
962 /// Opens a path as an object file and parses it into the linker.977 /// Opens a path as an object file and parses it into the linker.
963 fn openLoadObject(base: *File, path: Path) anyerror!void {978 fn openLoadObject(base: *File, path: Path) anyerror!void {
979 if (base.tag == .lld) return;
964 const diags = &base.comp.link_diags;980 const diags = &base.comp.link_diags;
965 const input = try openObjectInput(diags, path);981 const input = try openObjectInput(diags, path);
966 errdefer input.object.file.close();982 errdefer input.object.file.close();
...@@ -970,6 +986,7 @@ pub const File = struct {...@@ -970,6 +986,7 @@ pub const File = struct {
970 /// Opens a path as a static library and parses it into the linker.986 /// Opens a path as a static library and parses it into the linker.
971 /// If `query` is non-null, allows GNU ld scripts.987 /// If `query` is non-null, allows GNU ld scripts.
972 fn openLoadArchive(base: *File, path: Path, opt_query: ?UnresolvedInput.Query) anyerror!void {988 fn openLoadArchive(base: *File, path: Path, opt_query: ?UnresolvedInput.Query) anyerror!void {
989 if (base.tag == .lld) return;
973 if (opt_query) |query| {990 if (opt_query) |query| {
974 const archive = try openObject(path, query.must_link, query.hidden);991 const archive = try openObject(path, query.must_link, query.hidden);
975 errdefer archive.file.close();992 errdefer archive.file.close();
...@@ -992,6 +1009,7 @@ pub const File = struct {...@@ -992,6 +1009,7 @@ pub const File = struct {
992 /// Opens a path as a shared library and parses it into the linker.1009 /// Opens a path as a shared library and parses it into the linker.
993 /// Handles GNU ld scripts.1010 /// Handles GNU ld scripts.
994 fn openLoadDso(base: *File, path: Path, query: UnresolvedInput.Query) anyerror!void {1011 fn openLoadDso(base: *File, path: Path, query: UnresolvedInput.Query) anyerror!void {
1012 if (base.tag == .lld) return;
995 const dso = try openDso(path, query.needed, query.weak, query.reexport);1013 const dso = try openDso(path, query.needed, query.weak, query.reexport);
996 errdefer dso.file.close();1014 errdefer dso.file.close();
997 loadInput(base, .{ .dso = dso }) catch |err| switch (err) {1015 loadInput(base, .{ .dso = dso }) catch |err| switch (err) {
...@@ -1044,8 +1062,7 @@ pub const File = struct {...@@ -1044,8 +1062,7 @@ pub const File = struct {
1044 }1062 }
10451063
1046 pub fn loadInput(base: *File, input: Input) anyerror!void {1064 pub fn loadInput(base: *File, input: Input) anyerror!void {
1047 const use_lld = build_options.have_llvm and base.comp.config.use_lld;1065 if (base.tag == .lld) return;
1048 if (use_lld) return;
1049 switch (base.tag) {1066 switch (base.tag) {
1050 inline .elf, .wasm => |tag| {1067 inline .elf, .wasm => |tag| {
1051 dev.check(tag.devFeature());1068 dev.check(tag.devFeature());
...@@ -1057,186 +1074,23 @@ pub const File = struct {...@@ -1057,186 +1074,23 @@ pub const File = struct {
10571074
1058 /// Called when all linker inputs have been sent via `loadInput`. After1075 /// Called when all linker inputs have been sent via `loadInput`. After
1059 /// this, `loadInput` will not be called anymore.1076 /// this, `loadInput` will not be called anymore.
1060 pub fn prelink(base: *File, prog_node: std.Progress.Node) FlushError!void {1077 pub fn prelink(base: *File) FlushError!void {
1061 assert(!base.post_prelink);1078 assert(!base.post_prelink);
1062 const use_lld = build_options.have_llvm and base.comp.config.use_lld;
1063 if (use_lld) return;
10641079
1065 // In this case, an object file is created by the LLVM backend, so1080 // In this case, an object file is created by the LLVM backend, so
1066 // there is no prelink phase. The Zig code is linked as a standard1081 // there is no prelink phase. The Zig code is linked as a standard
1067 // object along with the others.1082 // object along with the others.
1068 if (base.zcu_object_sub_path != null) return;1083 if (base.zcu_object_basename != null) return;
10691084
1070 switch (base.tag) {1085 switch (base.tag) {
1071 inline .wasm => |tag| {1086 inline .wasm => |tag| {
1072 dev.check(tag.devFeature());1087 dev.check(tag.devFeature());
1073 return @as(*tag.Type(), @fieldParentPtr("base", base)).prelink(prog_node);1088 return @as(*tag.Type(), @fieldParentPtr("base", base)).prelink(base.comp.link_prog_node);
1074 },1089 },
1075 else => {},1090 else => {},
1076 }1091 }
1077 }1092 }
10781093
1079 pub fn linkAsArchive(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void {
1080 dev.check(.lld_linker);
1081
1082 const tracy = trace(@src());
1083 defer tracy.end();
1084
1085 const comp = base.comp;
1086 const diags = &comp.link_diags;
1087
1088 return linkAsArchiveInner(base, arena, tid, prog_node) catch |err| switch (err) {
1089 error.OutOfMemory => return error.OutOfMemory,
1090 error.LinkFailure => return error.LinkFailure,
1091 else => |e| return diags.fail("failed to link as archive: {s}", .{@errorName(e)}),
1092 };
1093 }
1094
1095 fn linkAsArchiveInner(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
1096 const comp = base.comp;
1097
1098 const directory = base.emit.root_dir; // Just an alias to make it shorter to type.
1099 const full_out_path = try directory.join(arena, &[_][]const u8{base.emit.sub_path});
1100 const full_out_path_z = try arena.dupeZ(u8, full_out_path);
1101 const opt_zcu = comp.zcu;
1102
1103 // If there is no Zig code to compile, then we should skip flushing the output file
1104 // because it will not be part of the linker line anyway.
1105 const zcu_obj_path: ?[]const u8 = if (opt_zcu != null) blk: {
1106 try base.flushModule(arena, tid, prog_node);
1107
1108 const dirname = fs.path.dirname(full_out_path_z) orelse ".";
1109 break :blk try fs.path.join(arena, &.{ dirname, base.zcu_object_sub_path.? });
1110 } else null;
1111
1112 log.debug("zcu_obj_path={s}", .{if (zcu_obj_path) |s| s else "(null)"});
1113
1114 const compiler_rt_path: ?Path = if (comp.compiler_rt_strat == .obj)
1115 comp.compiler_rt_obj.?.full_object_path
1116 else
1117 null;
1118
1119 const ubsan_rt_path: ?Path = if (comp.ubsan_rt_strat == .obj)
1120 comp.ubsan_rt_obj.?.full_object_path
1121 else
1122 null;
1123
1124 // This function follows the same pattern as link.Elf.linkWithLLD so if you want some
1125 // insight as to what's going on here you can read that function body which is more
1126 // well-commented.
1127
1128 const id_symlink_basename = "llvm-ar.id";
1129
1130 var man: Cache.Manifest = undefined;
1131 defer if (!base.disable_lld_caching) man.deinit();
1132
1133 const link_inputs = comp.link_inputs;
1134
1135 var digest: [Cache.hex_digest_len]u8 = undefined;
1136
1137 if (!base.disable_lld_caching) {
1138 man = comp.cache_parent.obtain();
1139
1140 // We are about to obtain this lock, so here we give other processes a chance first.
1141 base.releaseLock();
1142
1143 try hashInputs(&man, link_inputs);
1144
1145 for (comp.c_object_table.keys()) |key| {
1146 _ = try man.addFilePath(key.status.success.object_path, null);
1147 }
1148 for (comp.win32_resource_table.keys()) |key| {
1149 _ = try man.addFile(key.status.success.res_path, null);
1150 }
1151 try man.addOptionalFile(zcu_obj_path);
1152 try man.addOptionalFilePath(compiler_rt_path);
1153 try man.addOptionalFilePath(ubsan_rt_path);
1154
1155 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
1156 _ = try man.hit();
1157 digest = man.final();
1158
1159 var prev_digest_buf: [digest.len]u8 = undefined;
1160 const prev_digest: []u8 = Cache.readSmallFile(
1161 directory.handle,
1162 id_symlink_basename,
1163 &prev_digest_buf,
1164 ) catch |err| b: {
1165 log.debug("archive new_digest={s} readFile error: {s}", .{ std.fmt.fmtSliceHexLower(&digest), @errorName(err) });
1166 break :b prev_digest_buf[0..0];
1167 };
1168 if (mem.eql(u8, prev_digest, &digest)) {
1169 log.debug("archive digest={s} match - skipping invocation", .{std.fmt.fmtSliceHexLower(&digest)});
1170 base.lock = man.toOwnedLock();
1171 return;
1172 }
1173
1174 // We are about to change the output file to be different, so we invalidate the build hash now.
1175 directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) {
1176 error.FileNotFound => {},
1177 else => |e| return e,
1178 };
1179 }
1180
1181 var object_files: std.ArrayListUnmanaged([*:0]const u8) = .empty;
1182
1183 try object_files.ensureUnusedCapacity(arena, link_inputs.len);
1184 for (link_inputs) |input| {
1185 object_files.appendAssumeCapacity(try input.path().?.toStringZ(arena));
1186 }
1187
1188 try object_files.ensureUnusedCapacity(arena, comp.c_object_table.count() +
1189 comp.win32_resource_table.count() + 2);
1190
1191 for (comp.c_object_table.keys()) |key| {
1192 object_files.appendAssumeCapacity(try key.status.success.object_path.toStringZ(arena));
1193 }
1194 for (comp.win32_resource_table.keys()) |key| {
1195 object_files.appendAssumeCapacity(try arena.dupeZ(u8, key.status.success.res_path));
1196 }
1197 if (zcu_obj_path) |p| object_files.appendAssumeCapacity(try arena.dupeZ(u8, p));
1198 if (compiler_rt_path) |p| object_files.appendAssumeCapacity(try p.toStringZ(arena));
1199 if (ubsan_rt_path) |p| object_files.appendAssumeCapacity(try p.toStringZ(arena));
1200
1201 if (comp.verbose_link) {
1202 std.debug.print("ar rcs {s}", .{full_out_path_z});
1203 for (object_files.items) |arg| {
1204 std.debug.print(" {s}", .{arg});
1205 }
1206 std.debug.print("\n", .{});
1207 }
1208
1209 const llvm_bindings = @import("codegen/llvm/bindings.zig");
1210 const llvm = @import("codegen/llvm.zig");
1211 const target = comp.root_mod.resolved_target.result;
1212 llvm.initializeLLVMTarget(target.cpu.arch);
1213 const bad = llvm_bindings.WriteArchive(
1214 full_out_path_z,
1215 object_files.items.ptr,
1216 object_files.items.len,
1217 switch (target.os.tag) {
1218 .aix => .AIXBIG,
1219 .windows => .COFF,
1220 else => if (target.os.tag.isDarwin()) .DARWIN else .GNU,
1221 },
1222 );
1223 if (bad) return error.UnableToWriteArchive;
1224
1225 if (!base.disable_lld_caching) {
1226 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
1227 log.warn("failed to save archive hash digest file: {s}", .{@errorName(err)});
1228 };
1229
1230 if (man.have_exclusive_lock) {
1231 man.writeManifest() catch |err| {
1232 log.warn("failed to write cache manifest when archiving: {s}", .{@errorName(err)});
1233 };
1234 }
1235
1236 base.lock = man.toOwnedLock();
1237 }
1238 }
1239
1240 pub const Tag = enum {1094 pub const Tag = enum {
1241 coff,1095 coff,
1242 elf,1096 elf,
...@@ -1247,6 +1101,7 @@ pub const File = struct {...@@ -1247,6 +1101,7 @@ pub const File = struct {
1247 plan9,1101 plan9,
1248 goff,1102 goff,
1249 xcoff,1103 xcoff,
1104 lld,
12501105
1251 pub fn Type(comptime tag: Tag) type {1106 pub fn Type(comptime tag: Tag) type {
1252 return switch (tag) {1107 return switch (tag) {
...@@ -1259,10 +1114,11 @@ pub const File = struct {...@@ -1259,10 +1114,11 @@ pub const File = struct {
1259 .plan9 => Plan9,1114 .plan9 => Plan9,
1260 .goff => Goff,1115 .goff => Goff,
1261 .xcoff => Xcoff,1116 .xcoff => Xcoff,
1117 .lld => Lld,
1262 };1118 };
1263 }1119 }
12641120
1265 pub fn fromObjectFormat(ofmt: std.Target.ObjectFormat) Tag {1121 fn fromObjectFormat(ofmt: std.Target.ObjectFormat) Tag {
1266 return switch (ofmt) {1122 return switch (ofmt) {
1267 .coff => .coff,1123 .coff => .coff,
1268 .elf => .elf,1124 .elf => .elf,
...@@ -1290,15 +1146,7 @@ pub const File = struct {...@@ -1290,15 +1146,7 @@ pub const File = struct {
1290 ty: InternPool.Index,1146 ty: InternPool.Index,
1291 };1147 };
12921148
1293 pub fn effectiveOutputMode(
1294 use_lld: bool,
1295 output_mode: std.builtin.OutputMode,
1296 ) std.builtin.OutputMode {
1297 return if (use_lld) .Obj else output_mode;
1298 }
1299
1300 pub fn determineMode(1149 pub fn determineMode(
1301 use_lld: bool,
1302 output_mode: std.builtin.OutputMode,1150 output_mode: std.builtin.OutputMode,
1303 link_mode: std.builtin.LinkMode,1151 link_mode: std.builtin.LinkMode,
1304 ) fs.File.Mode {1152 ) fs.File.Mode {
...@@ -1307,7 +1155,7 @@ pub const File = struct {...@@ -1307,7 +1155,7 @@ pub const File = struct {
1307 // more leniently. As another data point, C's fopen seems to open files with the1155 // more leniently. As another data point, C's fopen seems to open files with the
1308 // 666 mode.1156 // 666 mode.
1309 const executable_mode = if (builtin.target.os.tag == .windows) 0 else 0o777;1157 const executable_mode = if (builtin.target.os.tag == .windows) 0 else 0o777;
1310 switch (effectiveOutputMode(use_lld, output_mode)) {1158 switch (output_mode) {
1311 .Lib => return switch (link_mode) {1159 .Lib => return switch (link_mode) {
1312 .dynamic => executable_mode,1160 .dynamic => executable_mode,
1313 .static => fs.File.default_mode,1161 .static => fs.File.default_mode,
...@@ -1345,21 +1193,6 @@ pub const File = struct {...@@ -1345,21 +1193,6 @@ pub const File = struct {
1345 return output_mode == .Lib and !self.isStatic();1193 return output_mode == .Lib and !self.isStatic();
1346 }1194 }
13471195
1348 pub fn emitLlvmObject(
1349 base: File,
1350 arena: Allocator,
1351 llvm_object: LlvmObject.Ptr,
1352 prog_node: std.Progress.Node,
1353 ) !void {
1354 return base.comp.emitLlvmObject(arena, .{
1355 .root_dir = base.emit.root_dir,
1356 .sub_path = std.fs.path.dirname(base.emit.sub_path) orelse "",
1357 }, .{
1358 .directory = null,
1359 .basename = base.zcu_object_sub_path.?,
1360 }, llvm_object, prog_node);
1361 }
1362
1363 pub fn cgFail(1196 pub fn cgFail(
1364 base: *File,1197 base: *File,
1365 nav_index: InternPool.Nav.Index,1198 nav_index: InternPool.Nav.Index,
...@@ -1370,6 +1203,7 @@ pub const File = struct {...@@ -1370,6 +1203,7 @@ pub const File = struct {
1370 return base.comp.zcu.?.codegenFail(nav_index, format, args);1203 return base.comp.zcu.?.codegenFail(nav_index, format, args);
1371 }1204 }
13721205
1206 pub const Lld = @import("link/Lld.zig");
1373 pub const C = @import("link/C.zig");1207 pub const C = @import("link/C.zig");
1374 pub const Coff = @import("link/Coff.zig");1208 pub const Coff = @import("link/Coff.zig");
1375 pub const Plan9 = @import("link/Plan9.zig");1209 pub const Plan9 = @import("link/Plan9.zig");
...@@ -1382,40 +1216,7 @@ pub const File = struct {...@@ -1382,40 +1216,7 @@ pub const File = struct {
1382 pub const Dwarf = @import("link/Dwarf.zig");1216 pub const Dwarf = @import("link/Dwarf.zig");
1383};1217};
13841218
1385/// Does all the tasks in the queue. Runs in exactly one separate thread1219pub const PrelinkTask = union(enum) {
1386/// from the rest of compilation. All tasks performed here are
1387/// single-threaded with respect to one another.
1388pub fn flushTaskQueue(tid: usize, comp: *Compilation) void {
1389 const diags = &comp.link_diags;
1390 // As soon as check() is called, another `flushTaskQueue` call could occur,
1391 // so the safety lock must go after the check.
1392 while (comp.link_task_queue.check()) |tasks| {
1393 comp.link_task_queue_safety.lock();
1394 defer comp.link_task_queue_safety.unlock();
1395
1396 if (comp.remaining_prelink_tasks > 0) {
1397 comp.link_task_queue_postponed.ensureUnusedCapacity(comp.gpa, tasks.len) catch |err| switch (err) {
1398 error.OutOfMemory => return diags.setAllocFailure(),
1399 };
1400 }
1401
1402 for (tasks) |task| doTask(comp, tid, task);
1403
1404 if (comp.remaining_prelink_tasks == 0) {
1405 if (comp.bin_file) |base| if (!base.post_prelink) {
1406 base.prelink(comp.work_queue_progress_node) catch |err| switch (err) {
1407 error.OutOfMemory => diags.setAllocFailure(),
1408 error.LinkFailure => continue,
1409 };
1410 base.post_prelink = true;
1411 for (comp.link_task_queue_postponed.items) |task| doTask(comp, tid, task);
1412 comp.link_task_queue_postponed.clearRetainingCapacity();
1413 };
1414 }
1415 }
1416}
1417
1418pub const Task = union(enum) {
1419 /// Loads the objects, shared objects, and archives that are already1220 /// Loads the objects, shared objects, and archives that are already
1420 /// known from the command line.1221 /// known from the command line.
1421 load_explicitly_provided,1222 load_explicitly_provided,
...@@ -1433,32 +1234,74 @@ pub const Task = union(enum) {...@@ -1433,32 +1234,74 @@ pub const Task = union(enum) {
1433 /// Tells the linker to load an input which could be an object file,1234 /// Tells the linker to load an input which could be an object file,
1434 /// archive, or shared library.1235 /// archive, or shared library.
1435 load_input: Input,1236 load_input: Input,
14361237};
1238pub const ZcuTask = union(enum) {
1437 /// Write the constant value for a Decl to the output file.1239 /// Write the constant value for a Decl to the output file.
1438 codegen_nav: InternPool.Nav.Index,1240 link_nav: InternPool.Nav.Index,
1439 /// Write the machine code for a function to the output file.1241 /// Write the machine code for a function to the output file.
1440 codegen_func: CodegenFunc,1242 link_func: LinkFunc,
1441 codegen_type: InternPool.Index,1243 link_type: InternPool.Index,
1442
1443 update_line_number: InternPool.TrackedInst.Index,1244 update_line_number: InternPool.TrackedInst.Index,
14441245 pub fn deinit(task: ZcuTask, zcu: *const Zcu) void {
1445 pub const CodegenFunc = struct {1246 switch (task) {
1247 .link_nav,
1248 .link_type,
1249 .update_line_number,
1250 => {},
1251 .link_func => |link_func| {
1252 switch (link_func.mir.status.load(.monotonic)) {
1253 .pending => unreachable, // cannot deinit until MIR done
1254 .failed => {}, // MIR not populated so doesn't need freeing
1255 .ready => link_func.mir.value.deinit(zcu),
1256 }
1257 zcu.gpa.destroy(link_func.mir);
1258 },
1259 }
1260 }
1261 pub const LinkFunc = struct {
1446 /// This will either be a non-generic `func_decl` or a `func_instance`.1262 /// This will either be a non-generic `func_decl` or a `func_instance`.
1447 func: InternPool.Index,1263 func: InternPool.Index,
1448 /// This `Air` is owned by the `Job` and allocated with `gpa`.1264 /// This pointer is allocated into `gpa` and must be freed when the `ZcuTask` is processed.
1449 /// It must be deinited when the job is processed.1265 /// The pointer is shared with the codegen worker, which will populate the MIR inside once
1450 air: Air,1266 /// it has been generated. It's important that the `link_func` is queued at the same time as
1267 /// the codegen job to ensure that the linker receives functions in a deterministic order,
1268 /// allowing reproducible builds.
1269 mir: *SharedMir,
1270 /// This is not actually used by `doZcuTask`. Instead, `Queue` uses this value as a heuristic
1271 /// to avoid queueing too much AIR/MIR for codegen/link at a time. Essentially, we cap the
1272 /// total number of AIR bytes which are being processed at once, preventing unbounded memory
1273 /// usage when AIR is produced faster than it is processed.
1274 air_bytes: u32,
1275
1276 pub const SharedMir = struct {
1277 /// This is initially `.pending`. When `value` is populated, the codegen thread will set
1278 /// this to `.ready`, and alert the queue if needed. It could also end up `.failed`.
1279 /// The action of storing a value (other than `.pending`) to this atomic transfers
1280 /// ownership of memory assoicated with `value` to this `ZcuTask`.
1281 status: std.atomic.Value(enum(u8) {
1282 /// We are waiting on codegen to generate MIR (or die trying).
1283 pending,
1284 /// `value` is not populated and will not be populated. Just drop the task from the queue and move on.
1285 failed,
1286 /// `value` is populated with the MIR from the backend in use, which is not LLVM.
1287 ready,
1288 }),
1289 /// This is `undefined` until `ready` is set to `true`. Once populated, this MIR belongs
1290 /// to the `ZcuTask`, and must be `deinit`ed when it is processed. Allocated into `gpa`.
1291 value: codegen.AnyMir,
1292 };
1451 };1293 };
1452};1294};
14531295
1454pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {1296pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void {
1455 const diags = &comp.link_diags;1297 const diags = &comp.link_diags;
1298 const base = comp.bin_file orelse {
1299 comp.link_prog_node.completeOne();
1300 return;
1301 };
1456 switch (task) {1302 switch (task) {
1457 .load_explicitly_provided => {1303 .load_explicitly_provided => {
1458 comp.remaining_prelink_tasks -= 1;1304 const prog_node = comp.link_prog_node.start("Parse Inputs", comp.link_inputs.len);
1459 const base = comp.bin_file orelse return;
1460
1461 const prog_node = comp.work_queue_progress_node.start("Parse Linker Inputs", comp.link_inputs.len);
1462 defer prog_node.end();1305 defer prog_node.end();
1463 for (comp.link_inputs) |input| {1306 for (comp.link_inputs) |input| {
1464 base.loadInput(input) catch |err| switch (err) {1307 base.loadInput(input) catch |err| switch (err) {
...@@ -1475,10 +1318,7 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {...@@ -1475,10 +1318,7 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {
1475 }1318 }
1476 },1319 },
1477 .load_host_libc => {1320 .load_host_libc => {
1478 comp.remaining_prelink_tasks -= 1;1321 const prog_node = comp.link_prog_node.start("Parse Host libc", 0);
1479 const base = comp.bin_file orelse return;
1480
1481 const prog_node = comp.work_queue_progress_node.start("Linker Parse Host libc", 0);
1482 defer prog_node.end();1322 defer prog_node.end();
14831323
1484 const target = comp.root_mod.resolved_target.result;1324 const target = comp.root_mod.resolved_target.result;
...@@ -1537,9 +1377,7 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {...@@ -1537,9 +1377,7 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {
1537 }1377 }
1538 },1378 },
1539 .load_object => |path| {1379 .load_object => |path| {
1540 comp.remaining_prelink_tasks -= 1;1380 const prog_node = comp.link_prog_node.start("Parse Object", 0);
1541 const base = comp.bin_file orelse return;
1542 const prog_node = comp.work_queue_progress_node.start("Linker Parse Object", 0);
1543 defer prog_node.end();1381 defer prog_node.end();
1544 base.openLoadObject(path) catch |err| switch (err) {1382 base.openLoadObject(path) catch |err| switch (err) {
1545 error.LinkFailure => return, // error reported via diags1383 error.LinkFailure => return, // error reported via diags
...@@ -1547,9 +1385,7 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {...@@ -1547,9 +1385,7 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {
1547 };1385 };
1548 },1386 },
1549 .load_archive => |path| {1387 .load_archive => |path| {
1550 comp.remaining_prelink_tasks -= 1;1388 const prog_node = comp.link_prog_node.start("Parse Archive", 0);
1551 const base = comp.bin_file orelse return;
1552 const prog_node = comp.work_queue_progress_node.start("Linker Parse Archive", 0);
1553 defer prog_node.end();1389 defer prog_node.end();
1554 base.openLoadArchive(path, null) catch |err| switch (err) {1390 base.openLoadArchive(path, null) catch |err| switch (err) {
1555 error.LinkFailure => return, // error reported via link_diags1391 error.LinkFailure => return, // error reported via link_diags
...@@ -1557,9 +1393,7 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {...@@ -1557,9 +1393,7 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {
1557 };1393 };
1558 },1394 },
1559 .load_dso => |path| {1395 .load_dso => |path| {
1560 comp.remaining_prelink_tasks -= 1;1396 const prog_node = comp.link_prog_node.start("Parse Shared Library", 0);
1561 const base = comp.bin_file orelse return;
1562 const prog_node = comp.work_queue_progress_node.start("Linker Parse Shared Library", 0);
1563 defer prog_node.end();1397 defer prog_node.end();
1564 base.openLoadDso(path, .{1398 base.openLoadDso(path, .{
1565 .preferred_mode = .dynamic,1399 .preferred_mode = .dynamic,
...@@ -1570,9 +1404,7 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {...@@ -1570,9 +1404,7 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {
1570 };1404 };
1571 },1405 },
1572 .load_input => |input| {1406 .load_input => |input| {
1573 comp.remaining_prelink_tasks -= 1;1407 const prog_node = comp.link_prog_node.start("Parse Input", 0);
1574 const base = comp.bin_file orelse return;
1575 const prog_node = comp.work_queue_progress_node.start("Linker Parse Input", 0);
1576 defer prog_node.end();1408 defer prog_node.end();
1577 base.loadInput(input) catch |err| switch (err) {1409 base.loadInput(input) catch |err| switch (err) {
1578 error.LinkFailure => return, // error reported via link_diags1410 error.LinkFailure => return, // error reported via link_diags
...@@ -1585,159 +1417,113 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {...@@ -1585,159 +1417,113 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {
1585 },1417 },
1586 };1418 };
1587 },1419 },
1588 .codegen_nav => |nav_index| {1420 }
1589 if (comp.remaining_prelink_tasks == 0) {1421}
1590 const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid));1422pub fn doZcuTask(comp: *Compilation, tid: usize, task: ZcuTask) void {
1591 defer pt.deactivate();1423 const diags = &comp.link_diags;
1592 pt.linkerUpdateNav(nav_index) catch |err| switch (err) {1424 const zcu = comp.zcu.?;
1425 const ip = &zcu.intern_pool;
1426 const pt: Zcu.PerThread = .activate(zcu, @enumFromInt(tid));
1427 defer pt.deactivate();
1428 switch (task) {
1429 .link_nav => |nav_index| {
1430 const fqn_slice = ip.getNav(nav_index).fqn.toSlice(ip);
1431 const nav_prog_node = comp.link_prog_node.start(fqn_slice, 0);
1432 defer nav_prog_node.end();
1433 if (zcu.llvm_object) |llvm_object| {
1434 llvm_object.updateNav(pt, nav_index) catch |err| switch (err) {
1593 error.OutOfMemory => diags.setAllocFailure(),1435 error.OutOfMemory => diags.setAllocFailure(),
1594 };1436 };
1595 } else {1437 } else if (comp.bin_file) |lf| {
1596 comp.link_task_queue_postponed.appendAssumeCapacity(task);1438 lf.updateNav(pt, nav_index) catch |err| switch (err) {
1597 }
1598 },
1599 .codegen_func => |func| {
1600 if (comp.remaining_prelink_tasks == 0) {
1601 const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid));
1602 defer pt.deactivate();
1603 var air = func.air;
1604 defer air.deinit(comp.gpa);
1605 pt.linkerUpdateFunc(func.func, &air) catch |err| switch (err) {
1606 error.OutOfMemory => diags.setAllocFailure(),1439 error.OutOfMemory => diags.setAllocFailure(),
1440 error.CodegenFail => zcu.assertCodegenFailed(nav_index),
1441 error.Overflow, error.RelocationNotByteAligned => {
1442 switch (zcu.codegenFail(nav_index, "unable to codegen: {s}", .{@errorName(err)})) {
1443 error.CodegenFail => return,
1444 error.OutOfMemory => return diags.setAllocFailure(),
1445 }
1446 // Not a retryable failure.
1447 },
1607 };1448 };
1608 } else {
1609 comp.link_task_queue_postponed.appendAssumeCapacity(task);
1610 }1449 }
1611 },1450 },
1612 .codegen_type => |ty| {1451 .link_func => |func| {
1613 if (comp.remaining_prelink_tasks == 0) {1452 const nav = zcu.funcInfo(func.func).owner_nav;
1614 const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid));1453 const fqn_slice = ip.getNav(nav).fqn.toSlice(ip);
1615 defer pt.deactivate();1454 const nav_prog_node = comp.link_prog_node.start(fqn_slice, 0);
1616 pt.linkerUpdateContainerType(ty) catch |err| switch (err) {1455 defer nav_prog_node.end();
1617 error.OutOfMemory => diags.setAllocFailure(),1456 switch (func.mir.status.load(.monotonic)) {
1457 .pending => unreachable,
1458 .ready => {},
1459 .failed => return,
1460 }
1461 assert(zcu.llvm_object == null); // LLVM codegen doesn't produce MIR
1462 const mir = &func.mir.value;
1463 if (comp.bin_file) |lf| {
1464 lf.updateFunc(pt, func.func, mir) catch |err| switch (err) {
1465 error.OutOfMemory => return diags.setAllocFailure(),
1466 error.CodegenFail => return zcu.assertCodegenFailed(nav),
1467 error.Overflow, error.RelocationNotByteAligned => {
1468 switch (zcu.codegenFail(nav, "unable to codegen: {s}", .{@errorName(err)})) {
1469 error.OutOfMemory => return diags.setAllocFailure(),
1470 error.CodegenFail => return,
1471 }
1472 },
1618 };1473 };
1619 } else {1474 }
1620 comp.link_task_queue_postponed.appendAssumeCapacity(task);1475 },
1476 .link_type => |ty| {
1477 const name = Type.fromInterned(ty).containerTypeName(ip).toSlice(ip);
1478 const nav_prog_node = comp.link_prog_node.start(name, 0);
1479 defer nav_prog_node.end();
1480 if (zcu.llvm_object == null) {
1481 if (comp.bin_file) |lf| {
1482 lf.updateContainerType(pt, ty) catch |err| switch (err) {
1483 error.OutOfMemory => diags.setAllocFailure(),
1484 error.TypeFailureReported => assert(zcu.failed_types.contains(ty)),
1485 };
1486 }
1621 }1487 }
1622 },1488 },
1623 .update_line_number => |ti| {1489 .update_line_number => |ti| {
1624 const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid));1490 const nav_prog_node = comp.link_prog_node.start("Update line number", 0);
1625 defer pt.deactivate();1491 defer nav_prog_node.end();
1626 pt.linkerUpdateLineNumber(ti) catch |err| switch (err) {1492 if (pt.zcu.llvm_object == null) {
1627 error.OutOfMemory => diags.setAllocFailure(),1493 if (comp.bin_file) |lf| {
1628 };1494 lf.updateLineNumber(pt, ti) catch |err| switch (err) {
1495 error.OutOfMemory => diags.setAllocFailure(),
1496 else => |e| log.err("update line number failed: {s}", .{@errorName(e)}),
1497 };
1498 }
1499 }
1629 },1500 },
1630 }1501 }
1631}1502}
16321503/// After the main pipeline is done, but before flush, the compilation may need to link one final
1633pub fn spawnLld(1504/// `Nav` into the binary: the `builtin.test_functions` value. Since the link thread isn't running
1634 comp: *Compilation,1505/// by then, we expose this function which can be called directly.
1635 arena: Allocator,1506pub fn linkTestFunctionsNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) void {
1636 argv: []const []const u8,1507 const zcu = pt.zcu;
1637) !void {1508 const comp = zcu.comp;
1638 if (comp.verbose_link) {1509 const diags = &comp.link_diags;
1639 // Skip over our own name so that the LLD linker name is the first argv item.1510 if (zcu.llvm_object) |llvm_object| {
1640 Compilation.dump_argv(argv[1..]);1511 llvm_object.updateNav(pt, nav_index) catch |err| switch (err) {
1641 }1512 error.OutOfMemory => diags.setAllocFailure(),
16421513 };
1643 // If possible, we run LLD as a child process because it does not always1514 } else if (comp.bin_file) |lf| {
1644 // behave properly as a library, unfortunately.1515 lf.updateNav(pt, nav_index) catch |err| switch (err) {
1645 // https://github.com/ziglang/zig/issues/38251516 error.OutOfMemory => diags.setAllocFailure(),
1646 if (!std.process.can_spawn) {1517 error.CodegenFail => zcu.assertCodegenFailed(nav_index),
1647 const exit_code = try lldMain(arena, argv, false);1518 error.Overflow, error.RelocationNotByteAligned => {
1648 if (exit_code == 0) return;1519 switch (zcu.codegenFail(nav_index, "unable to codegen: {s}", .{@errorName(err)})) {
1649 if (comp.clang_passthrough_mode) std.process.exit(exit_code);1520 error.CodegenFail => return,
1650 return error.LinkFailure;1521 error.OutOfMemory => return diags.setAllocFailure(),
1651 }
1652
1653 var stderr: []u8 = &.{};
1654 defer comp.gpa.free(stderr);
1655
1656 var child = std.process.Child.init(argv, arena);
1657 const term = (if (comp.clang_passthrough_mode) term: {
1658 child.stdin_behavior = .Inherit;
1659 child.stdout_behavior = .Inherit;
1660 child.stderr_behavior = .Inherit;
1661
1662 break :term child.spawnAndWait();
1663 } else term: {
1664 child.stdin_behavior = .Ignore;
1665 child.stdout_behavior = .Ignore;
1666 child.stderr_behavior = .Pipe;
1667
1668 child.spawn() catch |err| break :term err;
1669 stderr = try child.stderr.?.reader().readAllAlloc(comp.gpa, std.math.maxInt(usize));
1670 break :term child.wait();
1671 }) catch |first_err| term: {
1672 const err = switch (first_err) {
1673 error.NameTooLong => err: {
1674 const s = fs.path.sep_str;
1675 const rand_int = std.crypto.random.int(u64);
1676 const rsp_path = "tmp" ++ s ++ std.fmt.hex(rand_int) ++ ".rsp";
1677
1678 const rsp_file = try comp.dirs.local_cache.handle.createFileZ(rsp_path, .{});
1679 defer comp.dirs.local_cache.handle.deleteFileZ(rsp_path) catch |err|
1680 log.warn("failed to delete response file {s}: {s}", .{ rsp_path, @errorName(err) });
1681 {
1682 defer rsp_file.close();
1683 var rsp_buf = std.io.bufferedWriter(rsp_file.writer());
1684 const rsp_writer = rsp_buf.writer();
1685 for (argv[2..]) |arg| {
1686 try rsp_writer.writeByte('"');
1687 for (arg) |c| {
1688 switch (c) {
1689 '\"', '\\' => try rsp_writer.writeByte('\\'),
1690 else => {},
1691 }
1692 try rsp_writer.writeByte(c);
1693 }
1694 try rsp_writer.writeByte('"');
1695 try rsp_writer.writeByte('\n');
1696 }
1697 try rsp_buf.flush();
1698 }
1699
1700 var rsp_child = std.process.Child.init(&.{ argv[0], argv[1], try std.fmt.allocPrint(
1701 arena,
1702 "@{s}",
1703 .{try comp.dirs.local_cache.join(arena, &.{rsp_path})},
1704 ) }, arena);
1705 if (comp.clang_passthrough_mode) {
1706 rsp_child.stdin_behavior = .Inherit;
1707 rsp_child.stdout_behavior = .Inherit;
1708 rsp_child.stderr_behavior = .Inherit;
1709
1710 break :term rsp_child.spawnAndWait() catch |err| break :err err;
1711 } else {
1712 rsp_child.stdin_behavior = .Ignore;
1713 rsp_child.stdout_behavior = .Ignore;
1714 rsp_child.stderr_behavior = .Pipe;
1715
1716 rsp_child.spawn() catch |err| break :err err;
1717 stderr = try rsp_child.stderr.?.reader().readAllAlloc(comp.gpa, std.math.maxInt(usize));
1718 break :term rsp_child.wait() catch |err| break :err err;
1719 }1522 }
1523 // Not a retryable failure.
1720 },1524 },
1721 else => first_err,
1722 };1525 };
1723 log.err("unable to spawn LLD {s}: {s}", .{ argv[0], @errorName(err) });
1724 return error.UnableToSpawnSelf;
1725 };
1726
1727 const diags = &comp.link_diags;
1728 switch (term) {
1729 .Exited => |code| if (code != 0) {
1730 if (comp.clang_passthrough_mode) std.process.exit(code);
1731 diags.lockAndParseLldStderr(argv[1], stderr);
1732 return error.LinkFailure;
1733 },
1734 else => {
1735 if (comp.clang_passthrough_mode) std.process.abort();
1736 return diags.fail("{s} terminated with stderr:\n{s}", .{ argv[0], stderr });
1737 },
1738 }1526 }
1739
1740 if (stderr.len > 0) log.warn("unexpected LLD stderr:\n{s}", .{stderr});
1741}1527}
17421528
1743/// Provided by the CLI, processed into `LinkInput` instances at the start of1529/// Provided by the CLI, processed into `LinkInput` instances at the start of
src/link/C.zig+53-93
...@@ -17,7 +17,7 @@ const link = @import("../link.zig");...@@ -17,7 +17,7 @@ const link = @import("../link.zig");
17const trace = @import("../tracy.zig").trace;17const trace = @import("../tracy.zig").trace;
18const Type = @import("../Type.zig");18const Type = @import("../Type.zig");
19const Value = @import("../Value.zig");19const Value = @import("../Value.zig");
20const Air = @import("../Air.zig");20const AnyMir = @import("../codegen.zig").AnyMir;
2121
22pub const zig_h = "#include \"zig.h\"\n";22pub const zig_h = "#include \"zig.h\"\n";
2323
...@@ -145,7 +145,6 @@ pub fn createEmpty(...@@ -145,7 +145,6 @@ pub fn createEmpty(
145 .stack_size = options.stack_size orelse 16777216,145 .stack_size = options.stack_size orelse 16777216,
146 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,146 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
147 .file = file,147 .file = file,
148 .disable_lld_caching = options.disable_lld_caching,
149 .build_id = options.build_id,148 .build_id = options.build_id,
150 },149 },
151 };150 };
...@@ -167,6 +166,9 @@ pub fn deinit(self: *C) void {...@@ -167,6 +166,9 @@ pub fn deinit(self: *C) void {
167 self.uavs.deinit(gpa);166 self.uavs.deinit(gpa);
168 self.aligned_uavs.deinit(gpa);167 self.aligned_uavs.deinit(gpa);
169168
169 self.exported_navs.deinit(gpa);
170 self.exported_uavs.deinit(gpa);
171
170 self.string_bytes.deinit(gpa);172 self.string_bytes.deinit(gpa);
171 self.fwd_decl_buf.deinit(gpa);173 self.fwd_decl_buf.deinit(gpa);
172 self.code_buf.deinit(gpa);174 self.code_buf.deinit(gpa);
...@@ -178,73 +180,23 @@ pub fn updateFunc(...@@ -178,73 +180,23 @@ pub fn updateFunc(
178 self: *C,180 self: *C,
179 pt: Zcu.PerThread,181 pt: Zcu.PerThread,
180 func_index: InternPool.Index,182 func_index: InternPool.Index,
181 air: Air,183 mir: *AnyMir,
182 liveness: Air.Liveness,
183) link.File.UpdateNavError!void {184) link.File.UpdateNavError!void {
184 const zcu = pt.zcu;185 const zcu = pt.zcu;
185 const gpa = zcu.gpa;186 const gpa = zcu.gpa;
186 const func = zcu.funcInfo(func_index);187 const func = zcu.funcInfo(func_index);
187 const gop = try self.navs.getOrPut(gpa, func.owner_nav);
188 if (!gop.found_existing) gop.value_ptr.* = .{};
189 const ctype_pool = &gop.value_ptr.ctype_pool;
190 const lazy_fns = &gop.value_ptr.lazy_fns;
191 const fwd_decl = &self.fwd_decl_buf;
192 const code = &self.code_buf;
193 try ctype_pool.init(gpa);
194 ctype_pool.clearRetainingCapacity();
195 lazy_fns.clearRetainingCapacity();
196 fwd_decl.clearRetainingCapacity();
197 code.clearRetainingCapacity();
198
199 var function: codegen.Function = .{
200 .value_map = codegen.CValueMap.init(gpa),
201 .air = air,
202 .liveness = liveness,
203 .func_index = func_index,
204 .object = .{
205 .dg = .{
206 .gpa = gpa,
207 .pt = pt,
208 .mod = zcu.navFileScope(func.owner_nav).mod.?,
209 .error_msg = null,
210 .pass = .{ .nav = func.owner_nav },
211 .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked,
212 .expected_block = null,
213 .fwd_decl = fwd_decl.toManaged(gpa),
214 .ctype_pool = ctype_pool.*,
215 .scratch = .{},
216 .uav_deps = self.uavs,
217 .aligned_uavs = self.aligned_uavs,
218 },
219 .code = code.toManaged(gpa),
220 .indent_writer = undefined, // set later so we can get a pointer to object.code
221 },
222 .lazy_fns = lazy_fns.*,
223 };
224 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };
225 defer {
226 self.uavs = function.object.dg.uav_deps;
227 self.aligned_uavs = function.object.dg.aligned_uavs;
228 fwd_decl.* = function.object.dg.fwd_decl.moveToUnmanaged();
229 ctype_pool.* = function.object.dg.ctype_pool.move();
230 ctype_pool.freeUnusedCapacity(gpa);
231 function.object.dg.scratch.deinit(gpa);
232 lazy_fns.* = function.lazy_fns.move();
233 lazy_fns.shrinkAndFree(gpa, lazy_fns.count());
234 code.* = function.object.code.moveToUnmanaged();
235 function.deinit();
236 }
237188
238 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);189 const gop = try self.navs.getOrPut(gpa, func.owner_nav);
239 codegen.genFunc(&function) catch |err| switch (err) {190 if (gop.found_existing) gop.value_ptr.deinit(gpa);
240 error.AnalysisFail => {191 gop.value_ptr.* = .{
241 zcu.failed_codegen.putAssumeCapacityNoClobber(func.owner_nav, function.object.dg.error_msg.?);192 .code = .empty,
242 return;193 .fwd_decl = .empty,
243 },194 .ctype_pool = mir.c.ctype_pool.move(),
244 else => |e| return e,195 .lazy_fns = mir.c.lazy_fns.move(),
245 };196 };
246 gop.value_ptr.fwd_decl = try self.addString(function.object.dg.fwd_decl.items);197 gop.value_ptr.code = try self.addString(mir.c.code);
247 gop.value_ptr.code = try self.addString(function.object.code.items);198 gop.value_ptr.fwd_decl = try self.addString(mir.c.fwd_decl);
199 try self.addUavsFromCodegen(&mir.c.uavs);
248}200}
249201
250fn updateUav(self: *C, pt: Zcu.PerThread, i: usize) !void {202fn updateUav(self: *C, pt: Zcu.PerThread, i: usize) !void {
...@@ -268,16 +220,14 @@ fn updateUav(self: *C, pt: Zcu.PerThread, i: usize) !void {...@@ -268,16 +220,14 @@ fn updateUav(self: *C, pt: Zcu.PerThread, i: usize) !void {
268 .fwd_decl = fwd_decl.toManaged(gpa),220 .fwd_decl = fwd_decl.toManaged(gpa),
269 .ctype_pool = codegen.CType.Pool.empty,221 .ctype_pool = codegen.CType.Pool.empty,
270 .scratch = .{},222 .scratch = .{},
271 .uav_deps = self.uavs,223 .uavs = .empty,
272 .aligned_uavs = self.aligned_uavs,
273 },224 },
274 .code = code.toManaged(gpa),225 .code = code.toManaged(gpa),
275 .indent_writer = undefined, // set later so we can get a pointer to object.code226 .indent_writer = undefined, // set later so we can get a pointer to object.code
276 };227 };
277 object.indent_writer = .{ .underlying_writer = object.code.writer() };228 object.indent_writer = .{ .underlying_writer = object.code.writer() };
278 defer {229 defer {
279 self.uavs = object.dg.uav_deps;230 object.dg.uavs.deinit(gpa);
280 self.aligned_uavs = object.dg.aligned_uavs;
281 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();231 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
282 object.dg.ctype_pool.deinit(object.dg.gpa);232 object.dg.ctype_pool.deinit(object.dg.gpa);
283 object.dg.scratch.deinit(gpa);233 object.dg.scratch.deinit(gpa);
...@@ -296,8 +246,10 @@ fn updateUav(self: *C, pt: Zcu.PerThread, i: usize) !void {...@@ -296,8 +246,10 @@ fn updateUav(self: *C, pt: Zcu.PerThread, i: usize) !void {
296 else => |e| return e,246 else => |e| return e,
297 };247 };
298248
249 try self.addUavsFromCodegen(&object.dg.uavs);
250
299 object.dg.ctype_pool.freeUnusedCapacity(gpa);251 object.dg.ctype_pool.freeUnusedCapacity(gpa);
300 object.dg.uav_deps.values()[i] = .{252 self.uavs.values()[i] = .{
301 .code = try self.addString(object.code.items),253 .code = try self.addString(object.code.items),
302 .fwd_decl = try self.addString(object.dg.fwd_decl.items),254 .fwd_decl = try self.addString(object.dg.fwd_decl.items),
303 .ctype_pool = object.dg.ctype_pool.move(),255 .ctype_pool = object.dg.ctype_pool.move(),
...@@ -344,16 +296,14 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) l...@@ -344,16 +296,14 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) l
344 .fwd_decl = fwd_decl.toManaged(gpa),296 .fwd_decl = fwd_decl.toManaged(gpa),
345 .ctype_pool = ctype_pool.*,297 .ctype_pool = ctype_pool.*,
346 .scratch = .{},298 .scratch = .{},
347 .uav_deps = self.uavs,299 .uavs = .empty,
348 .aligned_uavs = self.aligned_uavs,
349 },300 },
350 .code = code.toManaged(gpa),301 .code = code.toManaged(gpa),
351 .indent_writer = undefined, // set later so we can get a pointer to object.code302 .indent_writer = undefined, // set later so we can get a pointer to object.code
352 };303 };
353 object.indent_writer = .{ .underlying_writer = object.code.writer() };304 object.indent_writer = .{ .underlying_writer = object.code.writer() };
354 defer {305 defer {
355 self.uavs = object.dg.uav_deps;306 object.dg.uavs.deinit(gpa);
356 self.aligned_uavs = object.dg.aligned_uavs;
357 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();307 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
358 ctype_pool.* = object.dg.ctype_pool.move();308 ctype_pool.* = object.dg.ctype_pool.move();
359 ctype_pool.freeUnusedCapacity(gpa);309 ctype_pool.freeUnusedCapacity(gpa);
...@@ -361,16 +311,16 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) l...@@ -361,16 +311,16 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) l
361 code.* = object.code.moveToUnmanaged();311 code.* = object.code.moveToUnmanaged();
362 }312 }
363313
364 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);
365 codegen.genDecl(&object) catch |err| switch (err) {314 codegen.genDecl(&object) catch |err| switch (err) {
366 error.AnalysisFail => {315 error.AnalysisFail => switch (zcu.codegenFailMsg(nav_index, object.dg.error_msg.?)) {
367 zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, object.dg.error_msg.?);316 error.CodegenFail => return,
368 return;317 error.OutOfMemory => |e| return e,
369 },318 },
370 else => |e| return e,319 else => |e| return e,
371 };320 };
372 gop.value_ptr.code = try self.addString(object.code.items);321 gop.value_ptr.code = try self.addString(object.code.items);
373 gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.items);322 gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.items);
323 try self.addUavsFromCodegen(&object.dg.uavs);
374}324}
375325
376pub fn updateLineNumber(self: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {326pub fn updateLineNumber(self: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
...@@ -381,10 +331,6 @@ pub fn updateLineNumber(self: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedIn...@@ -381,10 +331,6 @@ pub fn updateLineNumber(self: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedIn
381 _ = ti_id;331 _ = ti_id;
382}332}
383333
384pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
385 return self.flushModule(arena, tid, prog_node);
386}
387
388fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {334fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {
389 const gpa = self.base.comp.gpa;335 const gpa = self.base.comp.gpa;
390 var defines = std.ArrayList(u8).init(gpa);336 var defines = std.ArrayList(u8).init(gpa);
...@@ -400,7 +346,7 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {...@@ -400,7 +346,7 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {
400 return defines;346 return defines;
401}347}
402348
403pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {349pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
404 _ = arena; // Has the same lifetime as the call to Compilation.update.350 _ = arena; // Has the same lifetime as the call to Compilation.update.
405351
406 const tracy = trace(@src());352 const tracy = trace(@src());
...@@ -676,16 +622,14 @@ fn flushErrDecls(self: *C, pt: Zcu.PerThread, ctype_pool: *codegen.CType.Pool) F...@@ -676,16 +622,14 @@ fn flushErrDecls(self: *C, pt: Zcu.PerThread, ctype_pool: *codegen.CType.Pool) F
676 .fwd_decl = fwd_decl.toManaged(gpa),622 .fwd_decl = fwd_decl.toManaged(gpa),
677 .ctype_pool = ctype_pool.*,623 .ctype_pool = ctype_pool.*,
678 .scratch = .{},624 .scratch = .{},
679 .uav_deps = self.uavs,625 .uavs = .empty,
680 .aligned_uavs = self.aligned_uavs,
681 },626 },
682 .code = code.toManaged(gpa),627 .code = code.toManaged(gpa),
683 .indent_writer = undefined, // set later so we can get a pointer to object.code628 .indent_writer = undefined, // set later so we can get a pointer to object.code
684 };629 };
685 object.indent_writer = .{ .underlying_writer = object.code.writer() };630 object.indent_writer = .{ .underlying_writer = object.code.writer() };
686 defer {631 defer {
687 self.uavs = object.dg.uav_deps;632 object.dg.uavs.deinit(gpa);
688 self.aligned_uavs = object.dg.aligned_uavs;
689 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();633 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
690 ctype_pool.* = object.dg.ctype_pool.move();634 ctype_pool.* = object.dg.ctype_pool.move();
691 ctype_pool.freeUnusedCapacity(gpa);635 ctype_pool.freeUnusedCapacity(gpa);
...@@ -697,6 +641,8 @@ fn flushErrDecls(self: *C, pt: Zcu.PerThread, ctype_pool: *codegen.CType.Pool) F...@@ -697,6 +641,8 @@ fn flushErrDecls(self: *C, pt: Zcu.PerThread, ctype_pool: *codegen.CType.Pool) F
697 error.AnalysisFail => unreachable,641 error.AnalysisFail => unreachable,
698 else => |e| return e,642 else => |e| return e,
699 };643 };
644
645 try self.addUavsFromCodegen(&object.dg.uavs);
700}646}
701647
702fn flushLazyFn(648fn flushLazyFn(
...@@ -724,8 +670,7 @@ fn flushLazyFn(...@@ -724,8 +670,7 @@ fn flushLazyFn(
724 .fwd_decl = fwd_decl.toManaged(gpa),670 .fwd_decl = fwd_decl.toManaged(gpa),
725 .ctype_pool = ctype_pool.*,671 .ctype_pool = ctype_pool.*,
726 .scratch = .{},672 .scratch = .{},
727 .uav_deps = .{},673 .uavs = .empty,
728 .aligned_uavs = .{},
729 },674 },
730 .code = code.toManaged(gpa),675 .code = code.toManaged(gpa),
731 .indent_writer = undefined, // set later so we can get a pointer to object.code676 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -734,8 +679,7 @@ fn flushLazyFn(...@@ -734,8 +679,7 @@ fn flushLazyFn(
734 defer {679 defer {
735 // If this assert trips just handle the anon_decl_deps the same as680 // If this assert trips just handle the anon_decl_deps the same as
736 // `updateFunc()` does.681 // `updateFunc()` does.
737 assert(object.dg.uav_deps.count() == 0);682 assert(object.dg.uavs.count() == 0);
738 assert(object.dg.aligned_uavs.count() == 0);
739 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();683 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
740 ctype_pool.* = object.dg.ctype_pool.move();684 ctype_pool.* = object.dg.ctype_pool.move();
741 ctype_pool.freeUnusedCapacity(gpa);685 ctype_pool.freeUnusedCapacity(gpa);
...@@ -871,12 +815,10 @@ pub fn updateExports(...@@ -871,12 +815,10 @@ pub fn updateExports(
871 .fwd_decl = fwd_decl.toManaged(gpa),815 .fwd_decl = fwd_decl.toManaged(gpa),
872 .ctype_pool = decl_block.ctype_pool,816 .ctype_pool = decl_block.ctype_pool,
873 .scratch = .{},817 .scratch = .{},
874 .uav_deps = .{},818 .uavs = .empty,
875 .aligned_uavs = .{},
876 };819 };
877 defer {820 defer {
878 assert(dg.uav_deps.count() == 0);821 assert(dg.uavs.count() == 0);
879 assert(dg.aligned_uavs.count() == 0);
880 fwd_decl.* = dg.fwd_decl.moveToUnmanaged();822 fwd_decl.* = dg.fwd_decl.moveToUnmanaged();
881 ctype_pool.* = dg.ctype_pool.move();823 ctype_pool.* = dg.ctype_pool.move();
882 ctype_pool.freeUnusedCapacity(gpa);824 ctype_pool.freeUnusedCapacity(gpa);
...@@ -896,3 +838,21 @@ pub fn deleteExport(...@@ -896,3 +838,21 @@ pub fn deleteExport(
896 .uav => |uav| _ = self.exported_uavs.swapRemove(uav),838 .uav => |uav| _ = self.exported_uavs.swapRemove(uav),
897 }839 }
898}840}
841
842fn addUavsFromCodegen(c: *C, uavs: *const std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment)) Allocator.Error!void {
843 const gpa = c.base.comp.gpa;
844 try c.uavs.ensureUnusedCapacity(gpa, uavs.count());
845 try c.aligned_uavs.ensureUnusedCapacity(gpa, uavs.count());
846 for (uavs.keys(), uavs.values()) |uav_val, uav_align| {
847 {
848 const gop = c.uavs.getOrPutAssumeCapacity(uav_val);
849 if (!gop.found_existing) gop.value_ptr.* = .{};
850 }
851 if (uav_align != .none) {
852 const gop = c.aligned_uavs.getOrPutAssumeCapacity(uav_val);
853 gop.value_ptr.* = if (gop.found_existing) max: {
854 break :max gop.value_ptr.*.maxStrict(uav_align);
855 } else uav_align;
856 }
857 }
858}
src/link/Coff.zig+21-700
...@@ -1,26 +1,14 @@...@@ -1,26 +1,14 @@
1//! The main driver of the COFF linker.1//! The main driver of the self-hosted COFF linker.
2//! Currently uses our own implementation for the incremental linker, and falls back to
3//! LLD for traditional linking (linking relocatable object files).
4//! LLD is also the default linker for LLVM.
5
6/// If this is not null, an object file is created by LLVM and emitted to zcu_object_sub_path.
7llvm_object: ?LlvmObject.Ptr = null,
82
9base: link.File,3base: link.File,
10image_base: u64,4image_base: u64,
11subsystem: ?std.Target.SubSystem,
12tsaware: bool,
13nxcompat: bool,
14dynamicbase: bool,
15/// TODO this and minor_subsystem_version should be combined into one property and left as5/// TODO this and minor_subsystem_version should be combined into one property and left as
16/// default or populated together. They should not be separate fields.6/// default or populated together. They should not be separate fields.
17major_subsystem_version: u16,7major_subsystem_version: u16,
18minor_subsystem_version: u16,8minor_subsystem_version: u16,
19lib_directories: []const Directory,
20entry: link.File.OpenOptions.Entry,9entry: link.File.OpenOptions.Entry,
21entry_addr: ?u32,10entry_addr: ?u32,
22module_definition_file: ?[]const u8,11module_definition_file: ?[]const u8,
23pdb_out_path: ?[]const u8,
24repro: bool,12repro: bool,
2513
26ptr_width: PtrWidth,14ptr_width: PtrWidth,
...@@ -226,7 +214,6 @@ pub fn createEmpty(...@@ -226,7 +214,6 @@ pub fn createEmpty(
226 const output_mode = comp.config.output_mode;214 const output_mode = comp.config.output_mode;
227 const link_mode = comp.config.link_mode;215 const link_mode = comp.config.link_mode;
228 const use_llvm = comp.config.use_llvm;216 const use_llvm = comp.config.use_llvm;
229 const use_lld = build_options.have_llvm and comp.config.use_lld;
230217
231 const ptr_width: PtrWidth = switch (target.ptrBitWidth()) {218 const ptr_width: PtrWidth = switch (target.ptrBitWidth()) {
232 0...32 => .p32,219 0...32 => .p32,
...@@ -237,29 +224,21 @@ pub fn createEmpty(...@@ -237,29 +224,21 @@ pub fn createEmpty(
237 else => 0x1000,224 else => 0x1000,
238 };225 };
239226
240 // If using LLD to link, this code should produce an object file so that it
241 // can be passed to LLD.
242 // If using LLVM to generate the object file for the zig compilation unit,
243 // we need a place to put the object file so that it can be subsequently
244 // handled.
245 const zcu_object_sub_path = if (!use_lld and !use_llvm)
246 null
247 else
248 try allocPrint(arena, "{s}.obj", .{emit.sub_path});
249
250 const coff = try arena.create(Coff);227 const coff = try arena.create(Coff);
251 coff.* = .{228 coff.* = .{
252 .base = .{229 .base = .{
253 .tag = .coff,230 .tag = .coff,
254 .comp = comp,231 .comp = comp,
255 .emit = emit,232 .emit = emit,
256 .zcu_object_sub_path = zcu_object_sub_path,233 .zcu_object_basename = if (use_llvm)
234 try std.fmt.allocPrint(arena, "{s}_zcu.obj", .{fs.path.stem(emit.sub_path)})
235 else
236 null,
257 .stack_size = options.stack_size orelse 16777216,237 .stack_size = options.stack_size orelse 16777216,
258 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug),238 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug),
259 .print_gc_sections = options.print_gc_sections,239 .print_gc_sections = options.print_gc_sections,
260 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,240 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
261 .file = null,241 .file = null,
262 .disable_lld_caching = options.disable_lld_caching,
263 .build_id = options.build_id,242 .build_id = options.build_id,
264 },243 },
265 .ptr_width = ptr_width,244 .ptr_width = ptr_width,
...@@ -284,45 +263,23 @@ pub fn createEmpty(...@@ -284,45 +263,23 @@ pub fn createEmpty(
284 .Obj => 0,263 .Obj => 0,
285 },264 },
286265
287 // Subsystem depends on the set of public symbol names from linked objects.
288 // See LinkerDriver::inferSubsystem from the LLD project for the flow chart.
289 .subsystem = options.subsystem,
290
291 .entry = options.entry,266 .entry = options.entry,
292267
293 .tsaware = options.tsaware,
294 .nxcompat = options.nxcompat,
295 .dynamicbase = options.dynamicbase,
296 .major_subsystem_version = options.major_subsystem_version orelse 6,268 .major_subsystem_version = options.major_subsystem_version orelse 6,
297 .minor_subsystem_version = options.minor_subsystem_version orelse 0,269 .minor_subsystem_version = options.minor_subsystem_version orelse 0,
298 .lib_directories = options.lib_directories,
299 .entry_addr = math.cast(u32, options.entry_addr orelse 0) orelse270 .entry_addr = math.cast(u32, options.entry_addr orelse 0) orelse
300 return error.EntryAddressTooBig,271 return error.EntryAddressTooBig,
301 .module_definition_file = options.module_definition_file,272 .module_definition_file = options.module_definition_file,
302 .pdb_out_path = options.pdb_out_path,
303 .repro = options.repro,273 .repro = options.repro,
304 };274 };
305 if (use_llvm and comp.config.have_zcu) {
306 coff.llvm_object = try LlvmObject.create(arena, comp);
307 }
308 errdefer coff.base.destroy();275 errdefer coff.base.destroy();
309276
310 if (use_lld and (use_llvm or !comp.config.have_zcu)) {277 coff.base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{
311 // LLVM emits the object file (if any); LLD links it into the final product.
312 return coff;
313 }
314
315 // What path should this COFF linker code output to?
316 // If using LLD to link, this code should produce an object file so that it
317 // can be passed to LLD.
318 const sub_path = if (use_lld) zcu_object_sub_path.? else emit.sub_path;
319 coff.base.file = try emit.root_dir.handle.createFile(sub_path, .{
320 .truncate = true,278 .truncate = true,
321 .read = true,279 .read = true,
322 .mode = link.File.determineMode(use_lld, output_mode, link_mode),280 .mode = link.File.determineMode(output_mode, link_mode),
323 });281 });
324282
325 assert(coff.llvm_object == null);
326 const gpa = comp.gpa;283 const gpa = comp.gpa;
327284
328 try coff.strtab.buffer.ensureUnusedCapacity(gpa, @sizeOf(u32));285 try coff.strtab.buffer.ensureUnusedCapacity(gpa, @sizeOf(u32));
...@@ -428,8 +385,6 @@ pub fn open(...@@ -428,8 +385,6 @@ pub fn open(
428pub fn deinit(coff: *Coff) void {385pub fn deinit(coff: *Coff) void {
429 const gpa = coff.base.comp.gpa;386 const gpa = coff.base.comp.gpa;
430387
431 if (coff.llvm_object) |llvm_object| llvm_object.deinit();
432
433 for (coff.sections.items(.free_list)) |*free_list| {388 for (coff.sections.items(.free_list)) |*free_list| {
434 free_list.deinit(gpa);389 free_list.deinit(gpa);
435 }390 }
...@@ -1097,15 +1052,11 @@ pub fn updateFunc(...@@ -1097,15 +1052,11 @@ pub fn updateFunc(
1097 coff: *Coff,1052 coff: *Coff,
1098 pt: Zcu.PerThread,1053 pt: Zcu.PerThread,
1099 func_index: InternPool.Index,1054 func_index: InternPool.Index,
1100 air: Air,1055 mir: *const codegen.AnyMir,
1101 liveness: Air.Liveness,
1102) link.File.UpdateNavError!void {1056) link.File.UpdateNavError!void {
1103 if (build_options.skip_non_native and builtin.object_format != .coff) {1057 if (build_options.skip_non_native and builtin.object_format != .coff) {
1104 @panic("Attempted to compile for object format that was disabled by build configuration");1058 @panic("Attempted to compile for object format that was disabled by build configuration");
1105 }1059 }
1106 if (coff.llvm_object) |llvm_object| {
1107 return llvm_object.updateFunc(pt, func_index, air, liveness);
1108 }
1109 const tracy = trace(@src());1060 const tracy = trace(@src());
1110 defer tracy.end();1061 defer tracy.end();
11111062
...@@ -1122,29 +1073,15 @@ pub fn updateFunc(...@@ -1122,29 +1073,15 @@ pub fn updateFunc(
1122 var code_buffer: std.ArrayListUnmanaged(u8) = .empty;1073 var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
1123 defer code_buffer.deinit(gpa);1074 defer code_buffer.deinit(gpa);
11241075
1125 codegen.generateFunction(1076 try codegen.emitFunction(
1126 &coff.base,1077 &coff.base,
1127 pt,1078 pt,
1128 zcu.navSrcLoc(nav_index),1079 zcu.navSrcLoc(nav_index),
1129 func_index,1080 func_index,
1130 air,1081 mir,
1131 liveness,
1132 &code_buffer,1082 &code_buffer,
1133 .none,1083 .none,
1134 ) catch |err| switch (err) {1084 );
1135 error.CodegenFail => return error.CodegenFail,
1136 error.OutOfMemory => return error.OutOfMemory,
1137 error.Overflow, error.RelocationNotByteAligned => |e| {
1138 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
1139 gpa,
1140 zcu.navSrcLoc(nav_index),
1141 "unable to codegen: {s}",
1142 .{@errorName(e)},
1143 ));
1144 try zcu.retryable_failures.append(zcu.gpa, AnalUnit.wrap(.{ .func = func_index }));
1145 return error.CodegenFail;
1146 },
1147 };
11481085
1149 try coff.updateNavCode(pt, nav_index, code_buffer.items, .FUNCTION);1086 try coff.updateNavCode(pt, nav_index, code_buffer.items, .FUNCTION);
11501087
...@@ -1205,7 +1142,6 @@ pub fn updateNav(...@@ -1205,7 +1142,6 @@ pub fn updateNav(
1205 if (build_options.skip_non_native and builtin.object_format != .coff) {1142 if (build_options.skip_non_native and builtin.object_format != .coff) {
1206 @panic("Attempted to compile for object format that was disabled by build configuration");1143 @panic("Attempted to compile for object format that was disabled by build configuration");
1207 }1144 }
1208 if (coff.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav_index);
1209 const tracy = trace(@src());1145 const tracy = trace(@src());
1210 defer tracy.end();1146 defer tracy.end();
12111147
...@@ -1330,7 +1266,7 @@ pub fn getOrCreateAtomForLazySymbol(...@@ -1330,7 +1266,7 @@ pub fn getOrCreateAtomForLazySymbol(
1330 }1266 }
1331 state_ptr.* = .pending_flush;1267 state_ptr.* = .pending_flush;
1332 const atom = atom_ptr.*;1268 const atom = atom_ptr.*;
1333 // anyerror needs to be deferred until flushModule1269 // anyerror needs to be deferred until flush
1334 if (lazy_sym.ty != .anyerror_type) try coff.updateLazySymbolAtom(pt, lazy_sym, atom, switch (lazy_sym.kind) {1270 if (lazy_sym.ty != .anyerror_type) try coff.updateLazySymbolAtom(pt, lazy_sym, atom, switch (lazy_sym.kind) {
1335 .code => coff.text_section_index.?,1271 .code => coff.text_section_index.?,
1336 .const_data => coff.rdata_section_index.?,1272 .const_data => coff.rdata_section_index.?,
...@@ -1463,8 +1399,6 @@ fn updateNavCode(...@@ -1463,8 +1399,6 @@ fn updateNavCode(
1463}1399}
14641400
1465pub fn freeNav(coff: *Coff, nav_index: InternPool.NavIndex) void {1401pub fn freeNav(coff: *Coff, nav_index: InternPool.NavIndex) void {
1466 if (coff.llvm_object) |llvm_object| return llvm_object.freeNav(nav_index);
1467
1468 const gpa = coff.base.comp.gpa;1402 const gpa = coff.base.comp.gpa;
14691403
1470 if (coff.decls.fetchOrderedRemove(nav_index)) |const_kv| {1404 if (coff.decls.fetchOrderedRemove(nav_index)) |const_kv| {
...@@ -1485,50 +1419,7 @@ pub fn updateExports(...@@ -1485,50 +1419,7 @@ pub fn updateExports(
1485 }1419 }
14861420
1487 const zcu = pt.zcu;1421 const zcu = pt.zcu;
1488 const ip = &zcu.intern_pool;1422 const gpa = zcu.gpa;
1489 const comp = coff.base.comp;
1490 const target = comp.root_mod.resolved_target.result;
1491
1492 if (comp.config.use_llvm) {
1493 // Even in the case of LLVM, we need to notice certain exported symbols in order to
1494 // detect the default subsystem.
1495 for (export_indices) |export_idx| {
1496 const exp = export_idx.ptr(zcu);
1497 const exported_nav_index = switch (exp.exported) {
1498 .nav => |nav| nav,
1499 .uav => continue,
1500 };
1501 const exported_nav = ip.getNav(exported_nav_index);
1502 const exported_ty = exported_nav.typeOf(ip);
1503 if (!ip.isFunctionType(exported_ty)) continue;
1504 const c_cc = target.cCallingConvention().?;
1505 const winapi_cc: std.builtin.CallingConvention = switch (target.cpu.arch) {
1506 .x86 => .{ .x86_stdcall = .{} },
1507 else => c_cc,
1508 };
1509 const exported_cc = Type.fromInterned(exported_ty).fnCallingConvention(zcu);
1510 const CcTag = std.builtin.CallingConvention.Tag;
1511 if (@as(CcTag, exported_cc) == @as(CcTag, c_cc) and exp.opts.name.eqlSlice("main", ip) and comp.config.link_libc) {
1512 zcu.stage1_flags.have_c_main = true;
1513 } else if (@as(CcTag, exported_cc) == @as(CcTag, winapi_cc) and target.os.tag == .windows) {
1514 if (exp.opts.name.eqlSlice("WinMain", ip)) {
1515 zcu.stage1_flags.have_winmain = true;
1516 } else if (exp.opts.name.eqlSlice("wWinMain", ip)) {
1517 zcu.stage1_flags.have_wwinmain = true;
1518 } else if (exp.opts.name.eqlSlice("WinMainCRTStartup", ip)) {
1519 zcu.stage1_flags.have_winmain_crt_startup = true;
1520 } else if (exp.opts.name.eqlSlice("wWinMainCRTStartup", ip)) {
1521 zcu.stage1_flags.have_wwinmain_crt_startup = true;
1522 } else if (exp.opts.name.eqlSlice("DllMainCRTStartup", ip)) {
1523 zcu.stage1_flags.have_dllmain_crt_startup = true;
1524 }
1525 }
1526 }
1527 }
1528
1529 if (coff.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices);
1530
1531 const gpa = comp.gpa;
15321423
1533 const metadata = switch (exported) {1424 const metadata = switch (exported) {
1534 .nav => |nav| blk: {1425 .nav => |nav| blk: {
...@@ -1621,7 +1512,6 @@ pub fn deleteExport(...@@ -1621,7 +1512,6 @@ pub fn deleteExport(
1621 exported: Zcu.Exported,1512 exported: Zcu.Exported,
1622 name: InternPool.NullTerminatedString,1513 name: InternPool.NullTerminatedString,
1623) void {1514) void {
1624 if (coff.llvm_object) |_| return;
1625 const metadata = switch (exported) {1515 const metadata = switch (exported) {
1626 .nav => |nav| coff.navs.getPtr(nav),1516 .nav => |nav| coff.navs.getPtr(nav),
1627 .uav => |uav| coff.uavs.getPtr(uav),1517 .uav => |uav| coff.uavs.getPtr(uav),
...@@ -1680,571 +1570,7 @@ fn resolveGlobalSymbol(coff: *Coff, current: SymbolWithLoc) !void {...@@ -1680,571 +1570,7 @@ fn resolveGlobalSymbol(coff: *Coff, current: SymbolWithLoc) !void {
1680 gop.value_ptr.* = current;1570 gop.value_ptr.* = current;
1681}1571}
16821572
1683pub fn flush(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {1573pub fn flush(
1684 const comp = coff.base.comp;
1685 const use_lld = build_options.have_llvm and comp.config.use_lld;
1686 const diags = &comp.link_diags;
1687 if (use_lld) {
1688 return coff.linkWithLLD(arena, tid, prog_node) catch |err| switch (err) {
1689 error.OutOfMemory => return error.OutOfMemory,
1690 error.LinkFailure => return error.LinkFailure,
1691 else => |e| return diags.fail("failed to link with LLD: {s}", .{@errorName(e)}),
1692 };
1693 }
1694 switch (comp.config.output_mode) {
1695 .Exe, .Obj => return coff.flushModule(arena, tid, prog_node),
1696 .Lib => return diags.fail("writing lib files not yet implemented for COFF", .{}),
1697 }
1698}
1699
1700fn linkWithLLD(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
1701 dev.check(.lld_linker);
1702
1703 const tracy = trace(@src());
1704 defer tracy.end();
1705
1706 const comp = coff.base.comp;
1707 const gpa = comp.gpa;
1708
1709 const directory = coff.base.emit.root_dir; // Just an alias to make it shorter to type.
1710 const full_out_path = try directory.join(arena, &[_][]const u8{coff.base.emit.sub_path});
1711
1712 // If there is no Zig code to compile, then we should skip flushing the output file because it
1713 // will not be part of the linker line anyway.
1714 const module_obj_path: ?[]const u8 = if (comp.zcu != null) blk: {
1715 try coff.flushModule(arena, tid, prog_node);
1716
1717 if (fs.path.dirname(full_out_path)) |dirname| {
1718 break :blk try fs.path.join(arena, &.{ dirname, coff.base.zcu_object_sub_path.? });
1719 } else {
1720 break :blk coff.base.zcu_object_sub_path.?;
1721 }
1722 } else null;
1723
1724 const sub_prog_node = prog_node.start("LLD Link", 0);
1725 defer sub_prog_node.end();
1726
1727 const is_lib = comp.config.output_mode == .Lib;
1728 const is_dyn_lib = comp.config.link_mode == .dynamic and is_lib;
1729 const is_exe_or_dyn_lib = is_dyn_lib or comp.config.output_mode == .Exe;
1730 const link_in_crt = comp.config.link_libc and is_exe_or_dyn_lib;
1731 const target = comp.root_mod.resolved_target.result;
1732 const optimize_mode = comp.root_mod.optimize_mode;
1733 const entry_name: ?[]const u8 = switch (coff.entry) {
1734 // This logic isn't quite right for disabled or enabled. No point in fixing it
1735 // when the goal is to eliminate dependency on LLD anyway.
1736 // https://github.com/ziglang/zig/issues/17751
1737 .disabled, .default, .enabled => null,
1738 .named => |name| name,
1739 };
1740
1741 // See link/Elf.zig for comments on how this mechanism works.
1742 const id_symlink_basename = "lld.id";
1743
1744 var man: Cache.Manifest = undefined;
1745 defer if (!coff.base.disable_lld_caching) man.deinit();
1746
1747 var digest: [Cache.hex_digest_len]u8 = undefined;
1748
1749 if (!coff.base.disable_lld_caching) {
1750 man = comp.cache_parent.obtain();
1751 coff.base.releaseLock();
1752
1753 comptime assert(Compilation.link_hash_implementation_version == 14);
1754
1755 try link.hashInputs(&man, comp.link_inputs);
1756 for (comp.c_object_table.keys()) |key| {
1757 _ = try man.addFilePath(key.status.success.object_path, null);
1758 }
1759 for (comp.win32_resource_table.keys()) |key| {
1760 _ = try man.addFile(key.status.success.res_path, null);
1761 }
1762 try man.addOptionalFile(module_obj_path);
1763 man.hash.addOptionalBytes(entry_name);
1764 man.hash.add(coff.base.stack_size);
1765 man.hash.add(coff.image_base);
1766 man.hash.add(coff.base.build_id);
1767 {
1768 // TODO remove this, libraries must instead be resolved by the frontend.
1769 for (coff.lib_directories) |lib_directory| man.hash.addOptionalBytes(lib_directory.path);
1770 }
1771 man.hash.add(comp.skip_linker_dependencies);
1772 if (comp.config.link_libc) {
1773 man.hash.add(comp.libc_installation != null);
1774 if (comp.libc_installation) |libc_installation| {
1775 man.hash.addBytes(libc_installation.crt_dir.?);
1776 if (target.abi == .msvc or target.abi == .itanium) {
1777 man.hash.addBytes(libc_installation.msvc_lib_dir.?);
1778 man.hash.addBytes(libc_installation.kernel32_lib_dir.?);
1779 }
1780 }
1781 }
1782 man.hash.addListOfBytes(comp.windows_libs.keys());
1783 man.hash.addListOfBytes(comp.force_undefined_symbols.keys());
1784 man.hash.addOptional(coff.subsystem);
1785 man.hash.add(comp.config.is_test);
1786 man.hash.add(coff.tsaware);
1787 man.hash.add(coff.nxcompat);
1788 man.hash.add(coff.dynamicbase);
1789 man.hash.add(coff.base.allow_shlib_undefined);
1790 // strip does not need to go into the linker hash because it is part of the hash namespace
1791 man.hash.add(coff.major_subsystem_version);
1792 man.hash.add(coff.minor_subsystem_version);
1793 man.hash.add(coff.repro);
1794 man.hash.addOptional(comp.version);
1795 try man.addOptionalFile(coff.module_definition_file);
1796
1797 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
1798 _ = try man.hit();
1799 digest = man.final();
1800 var prev_digest_buf: [digest.len]u8 = undefined;
1801 const prev_digest: []u8 = Cache.readSmallFile(
1802 directory.handle,
1803 id_symlink_basename,
1804 &prev_digest_buf,
1805 ) catch |err| blk: {
1806 log.debug("COFF LLD new_digest={s} error: {s}", .{ std.fmt.fmtSliceHexLower(&digest), @errorName(err) });
1807 // Handle this as a cache miss.
1808 break :blk prev_digest_buf[0..0];
1809 };
1810 if (mem.eql(u8, prev_digest, &digest)) {
1811 log.debug("COFF LLD digest={s} match - skipping invocation", .{std.fmt.fmtSliceHexLower(&digest)});
1812 // Hot diggity dog! The output binary is already there.
1813 coff.base.lock = man.toOwnedLock();
1814 return;
1815 }
1816 log.debug("COFF LLD prev_digest={s} new_digest={s}", .{ std.fmt.fmtSliceHexLower(prev_digest), std.fmt.fmtSliceHexLower(&digest) });
1817
1818 // We are about to change the output file to be different, so we invalidate the build hash now.
1819 directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) {
1820 error.FileNotFound => {},
1821 else => |e| return e,
1822 };
1823 }
1824
1825 if (comp.config.output_mode == .Obj) {
1826 // LLD's COFF driver does not support the equivalent of `-r` so we do a simple file copy
1827 // here. TODO: think carefully about how we can avoid this redundant operation when doing
1828 // build-obj. See also the corresponding TODO in linkAsArchive.
1829 const the_object_path = blk: {
1830 if (link.firstObjectInput(comp.link_inputs)) |obj| break :blk obj.path;
1831
1832 if (comp.c_object_table.count() != 0)
1833 break :blk comp.c_object_table.keys()[0].status.success.object_path;
1834
1835 if (module_obj_path) |p|
1836 break :blk Path.initCwd(p);
1837
1838 // TODO I think this is unreachable. Audit this situation when solving the above TODO
1839 // regarding eliding redundant object -> object transformations.
1840 return error.NoObjectsToLink;
1841 };
1842 try std.fs.Dir.copyFile(
1843 the_object_path.root_dir.handle,
1844 the_object_path.sub_path,
1845 directory.handle,
1846 coff.base.emit.sub_path,
1847 .{},
1848 );
1849 } else {
1850 // Create an LLD command line and invoke it.
1851 var argv = std.ArrayList([]const u8).init(gpa);
1852 defer argv.deinit();
1853 // We will invoke ourselves as a child process to gain access to LLD.
1854 // This is necessary because LLD does not behave properly as a library -
1855 // it calls exit() and does not reset all global data between invocations.
1856 const linker_command = "lld-link";
1857 try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command });
1858
1859 if (target.isMinGW()) {
1860 try argv.append("-lldmingw");
1861 }
1862
1863 try argv.append("-ERRORLIMIT:0");
1864 try argv.append("-NOLOGO");
1865 if (comp.config.debug_format != .strip) {
1866 try argv.append("-DEBUG");
1867
1868 const out_ext = std.fs.path.extension(full_out_path);
1869 const out_pdb = coff.pdb_out_path orelse try allocPrint(arena, "{s}.pdb", .{
1870 full_out_path[0 .. full_out_path.len - out_ext.len],
1871 });
1872 const out_pdb_basename = std.fs.path.basename(out_pdb);
1873
1874 try argv.append(try allocPrint(arena, "-PDB:{s}", .{out_pdb}));
1875 try argv.append(try allocPrint(arena, "-PDBALTPATH:{s}", .{out_pdb_basename}));
1876 }
1877 if (comp.version) |version| {
1878 try argv.append(try allocPrint(arena, "-VERSION:{}.{}", .{ version.major, version.minor }));
1879 }
1880
1881 if (target_util.llvmMachineAbi(target)) |mabi| {
1882 try argv.append(try allocPrint(arena, "-MLLVM:-target-abi={s}", .{mabi}));
1883 }
1884
1885 try argv.append(try allocPrint(arena, "-MLLVM:-float-abi={s}", .{if (target.abi.float() == .hard) "hard" else "soft"}));
1886
1887 if (comp.config.lto != .none) {
1888 switch (optimize_mode) {
1889 .Debug => {},
1890 .ReleaseSmall => try argv.append("-OPT:lldlto=2"),
1891 .ReleaseFast, .ReleaseSafe => try argv.append("-OPT:lldlto=3"),
1892 }
1893 }
1894 if (comp.config.output_mode == .Exe) {
1895 try argv.append(try allocPrint(arena, "-STACK:{d}", .{coff.base.stack_size}));
1896 }
1897 try argv.append(try allocPrint(arena, "-BASE:{d}", .{coff.image_base}));
1898
1899 switch (coff.base.build_id) {
1900 .none => try argv.append("-BUILD-ID:NO"),
1901 .fast => try argv.append("-BUILD-ID"),
1902 .uuid, .sha1, .md5, .hexstring => {},
1903 }
1904
1905 if (target.cpu.arch == .x86) {
1906 try argv.append("-MACHINE:X86");
1907 } else if (target.cpu.arch == .x86_64) {
1908 try argv.append("-MACHINE:X64");
1909 } else if (target.cpu.arch == .thumb) {
1910 try argv.append("-MACHINE:ARM");
1911 } else if (target.cpu.arch == .aarch64) {
1912 try argv.append("-MACHINE:ARM64");
1913 }
1914
1915 for (comp.force_undefined_symbols.keys()) |symbol| {
1916 try argv.append(try allocPrint(arena, "-INCLUDE:{s}", .{symbol}));
1917 }
1918
1919 if (is_dyn_lib) {
1920 try argv.append("-DLL");
1921 }
1922
1923 if (entry_name) |name| {
1924 try argv.append(try allocPrint(arena, "-ENTRY:{s}", .{name}));
1925 }
1926
1927 if (coff.repro) {
1928 try argv.append("-BREPRO");
1929 }
1930
1931 if (coff.tsaware) {
1932 try argv.append("-tsaware");
1933 }
1934 if (coff.nxcompat) {
1935 try argv.append("-nxcompat");
1936 }
1937 if (!coff.dynamicbase) {
1938 try argv.append("-dynamicbase:NO");
1939 }
1940 if (coff.base.allow_shlib_undefined) {
1941 try argv.append("-FORCE:UNRESOLVED");
1942 }
1943
1944 try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path}));
1945
1946 if (comp.implib_emit) |emit| {
1947 const implib_out_path = try emit.root_dir.join(arena, &[_][]const u8{emit.sub_path});
1948 try argv.append(try allocPrint(arena, "-IMPLIB:{s}", .{implib_out_path}));
1949 }
1950
1951 if (comp.config.link_libc) {
1952 if (comp.libc_installation) |libc_installation| {
1953 try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.crt_dir.?}));
1954
1955 if (target.abi == .msvc or target.abi == .itanium) {
1956 try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.msvc_lib_dir.?}));
1957 try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.kernel32_lib_dir.?}));
1958 }
1959 }
1960 }
1961
1962 for (coff.lib_directories) |lib_directory| {
1963 try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_directory.path orelse "."}));
1964 }
1965
1966 try argv.ensureUnusedCapacity(comp.link_inputs.len);
1967 for (comp.link_inputs) |link_input| switch (link_input) {
1968 .dso_exact => unreachable, // not applicable to PE/COFF
1969 inline .dso, .res => |x| {
1970 argv.appendAssumeCapacity(try x.path.toString(arena));
1971 },
1972 .object, .archive => |obj| {
1973 if (obj.must_link) {
1974 argv.appendAssumeCapacity(try allocPrint(arena, "-WHOLEARCHIVE:{}", .{@as(Path, obj.path)}));
1975 } else {
1976 argv.appendAssumeCapacity(try obj.path.toString(arena));
1977 }
1978 },
1979 };
1980
1981 for (comp.c_object_table.keys()) |key| {
1982 try argv.append(try key.status.success.object_path.toString(arena));
1983 }
1984
1985 for (comp.win32_resource_table.keys()) |key| {
1986 try argv.append(key.status.success.res_path);
1987 }
1988
1989 if (module_obj_path) |p| {
1990 try argv.append(p);
1991 }
1992
1993 if (coff.module_definition_file) |def| {
1994 try argv.append(try allocPrint(arena, "-DEF:{s}", .{def}));
1995 }
1996
1997 const resolved_subsystem: ?std.Target.SubSystem = blk: {
1998 if (coff.subsystem) |explicit| break :blk explicit;
1999 switch (target.os.tag) {
2000 .windows => {
2001 if (comp.zcu) |module| {
2002 if (module.stage1_flags.have_dllmain_crt_startup or is_dyn_lib)
2003 break :blk null;
2004 if (module.stage1_flags.have_c_main or comp.config.is_test or
2005 module.stage1_flags.have_winmain_crt_startup or
2006 module.stage1_flags.have_wwinmain_crt_startup)
2007 {
2008 break :blk .Console;
2009 }
2010 if (module.stage1_flags.have_winmain or module.stage1_flags.have_wwinmain)
2011 break :blk .Windows;
2012 }
2013 },
2014 .uefi => break :blk .EfiApplication,
2015 else => {},
2016 }
2017 break :blk null;
2018 };
2019
2020 const Mode = enum { uefi, win32 };
2021 const mode: Mode = mode: {
2022 if (resolved_subsystem) |subsystem| {
2023 const subsystem_suffix = try allocPrint(arena, ",{d}.{d}", .{
2024 coff.major_subsystem_version, coff.minor_subsystem_version,
2025 });
2026
2027 switch (subsystem) {
2028 .Console => {
2029 try argv.append(try allocPrint(arena, "-SUBSYSTEM:console{s}", .{
2030 subsystem_suffix,
2031 }));
2032 break :mode .win32;
2033 },
2034 .EfiApplication => {
2035 try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_application{s}", .{
2036 subsystem_suffix,
2037 }));
2038 break :mode .uefi;
2039 },
2040 .EfiBootServiceDriver => {
2041 try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_boot_service_driver{s}", .{
2042 subsystem_suffix,
2043 }));
2044 break :mode .uefi;
2045 },
2046 .EfiRom => {
2047 try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_rom{s}", .{
2048 subsystem_suffix,
2049 }));
2050 break :mode .uefi;
2051 },
2052 .EfiRuntimeDriver => {
2053 try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_runtime_driver{s}", .{
2054 subsystem_suffix,
2055 }));
2056 break :mode .uefi;
2057 },
2058 .Native => {
2059 try argv.append(try allocPrint(arena, "-SUBSYSTEM:native{s}", .{
2060 subsystem_suffix,
2061 }));
2062 break :mode .win32;
2063 },
2064 .Posix => {
2065 try argv.append(try allocPrint(arena, "-SUBSYSTEM:posix{s}", .{
2066 subsystem_suffix,
2067 }));
2068 break :mode .win32;
2069 },
2070 .Windows => {
2071 try argv.append(try allocPrint(arena, "-SUBSYSTEM:windows{s}", .{
2072 subsystem_suffix,
2073 }));
2074 break :mode .win32;
2075 },
2076 }
2077 } else if (target.os.tag == .uefi) {
2078 break :mode .uefi;
2079 } else {
2080 break :mode .win32;
2081 }
2082 };
2083
2084 switch (mode) {
2085 .uefi => try argv.appendSlice(&[_][]const u8{
2086 "-BASE:0",
2087 "-ENTRY:EfiMain",
2088 "-OPT:REF",
2089 "-SAFESEH:NO",
2090 "-MERGE:.rdata=.data",
2091 "-NODEFAULTLIB",
2092 "-SECTION:.xdata,D",
2093 }),
2094 .win32 => {
2095 if (link_in_crt) {
2096 if (target.abi.isGnu()) {
2097 if (target.cpu.arch == .x86) {
2098 try argv.append("-ALTERNATENAME:__image_base__=___ImageBase");
2099 } else {
2100 try argv.append("-ALTERNATENAME:__image_base__=__ImageBase");
2101 }
2102
2103 if (is_dyn_lib) {
2104 try argv.append(try comp.crtFileAsString(arena, "dllcrt2.obj"));
2105 if (target.cpu.arch == .x86) {
2106 try argv.append("-ALTERNATENAME:__DllMainCRTStartup@12=_DllMainCRTStartup@12");
2107 } else {
2108 try argv.append("-ALTERNATENAME:_DllMainCRTStartup=DllMainCRTStartup");
2109 }
2110 } else {
2111 try argv.append(try comp.crtFileAsString(arena, "crt2.obj"));
2112 }
2113
2114 try argv.append(try comp.crtFileAsString(arena, "libmingw32.lib"));
2115 } else {
2116 try argv.append(switch (comp.config.link_mode) {
2117 .static => "libcmt.lib",
2118 .dynamic => "msvcrt.lib",
2119 });
2120
2121 const lib_str = switch (comp.config.link_mode) {
2122 .static => "lib",
2123 .dynamic => "",
2124 };
2125 try argv.append(try allocPrint(arena, "{s}vcruntime.lib", .{lib_str}));
2126 try argv.append(try allocPrint(arena, "{s}ucrt.lib", .{lib_str}));
2127
2128 //Visual C++ 2015 Conformance Changes
2129 //https://msdn.microsoft.com/en-us/library/bb531344.aspx
2130 try argv.append("legacy_stdio_definitions.lib");
2131
2132 // msvcrt depends on kernel32 and ntdll
2133 try argv.append("kernel32.lib");
2134 try argv.append("ntdll.lib");
2135 }
2136 } else {
2137 try argv.append("-NODEFAULTLIB");
2138 if (!is_lib and entry_name == null) {
2139 if (comp.zcu) |module| {
2140 if (module.stage1_flags.have_winmain_crt_startup) {
2141 try argv.append("-ENTRY:WinMainCRTStartup");
2142 } else {
2143 try argv.append("-ENTRY:wWinMainCRTStartup");
2144 }
2145 } else {
2146 try argv.append("-ENTRY:wWinMainCRTStartup");
2147 }
2148 }
2149 }
2150 },
2151 }
2152
2153 if (comp.config.link_libc and link_in_crt) {
2154 if (comp.zigc_static_lib) |zigc| {
2155 try argv.append(try zigc.full_object_path.toString(arena));
2156 }
2157 }
2158
2159 // libc++ dep
2160 if (comp.config.link_libcpp) {
2161 try argv.append(try comp.libcxxabi_static_lib.?.full_object_path.toString(arena));
2162 try argv.append(try comp.libcxx_static_lib.?.full_object_path.toString(arena));
2163 }
2164
2165 // libunwind dep
2166 if (comp.config.link_libunwind) {
2167 try argv.append(try comp.libunwind_static_lib.?.full_object_path.toString(arena));
2168 }
2169
2170 if (comp.config.any_fuzz) {
2171 try argv.append(try comp.fuzzer_lib.?.full_object_path.toString(arena));
2172 }
2173
2174 const ubsan_rt_path: ?Path = blk: {
2175 if (comp.ubsan_rt_lib) |x| break :blk x.full_object_path;
2176 if (comp.ubsan_rt_obj) |x| break :blk x.full_object_path;
2177 break :blk null;
2178 };
2179 if (ubsan_rt_path) |path| {
2180 try argv.append(try path.toString(arena));
2181 }
2182
2183 if (is_exe_or_dyn_lib and !comp.skip_linker_dependencies) {
2184 // MSVC compiler_rt is missing some stuff, so we build it unconditionally but
2185 // and rely on weak linkage to allow MSVC compiler_rt functions to override ours.
2186 if (comp.compiler_rt_obj) |obj| try argv.append(try obj.full_object_path.toString(arena));
2187 if (comp.compiler_rt_lib) |lib| try argv.append(try lib.full_object_path.toString(arena));
2188 }
2189
2190 try argv.ensureUnusedCapacity(comp.windows_libs.count());
2191 for (comp.windows_libs.keys()) |key| {
2192 const lib_basename = try allocPrint(arena, "{s}.lib", .{key});
2193 if (comp.crt_files.get(lib_basename)) |crt_file| {
2194 argv.appendAssumeCapacity(try crt_file.full_object_path.toString(arena));
2195 continue;
2196 }
2197 if (try findLib(arena, lib_basename, coff.lib_directories)) |full_path| {
2198 argv.appendAssumeCapacity(full_path);
2199 continue;
2200 }
2201 if (target.abi.isGnu()) {
2202 const fallback_name = try allocPrint(arena, "lib{s}.dll.a", .{key});
2203 if (try findLib(arena, fallback_name, coff.lib_directories)) |full_path| {
2204 argv.appendAssumeCapacity(full_path);
2205 continue;
2206 }
2207 }
2208 if (target.abi == .msvc or target.abi == .itanium) {
2209 argv.appendAssumeCapacity(lib_basename);
2210 continue;
2211 }
2212
2213 log.err("DLL import library for -l{s} not found", .{key});
2214 return error.DllImportLibraryNotFound;
2215 }
2216
2217 try link.spawnLld(comp, arena, argv.items);
2218 }
2219
2220 if (!coff.base.disable_lld_caching) {
2221 // Update the file with the digest. If it fails we can continue; it only
2222 // means that the next invocation will have an unnecessary cache miss.
2223 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
2224 log.warn("failed to save linking hash digest file: {s}", .{@errorName(err)});
2225 };
2226 // Again failure here only means an unnecessary cache miss.
2227 man.writeManifest() catch |err| {
2228 log.warn("failed to write cache manifest when linking: {s}", .{@errorName(err)});
2229 };
2230 // We hang on to this lock so that the output file path can be used without
2231 // other processes clobbering it.
2232 coff.base.lock = man.toOwnedLock();
2233 }
2234}
2235
2236fn findLib(arena: Allocator, name: []const u8, lib_directories: []const Directory) !?[]const u8 {
2237 for (lib_directories) |lib_directory| {
2238 lib_directory.handle.access(name, .{}) catch |err| switch (err) {
2239 error.FileNotFound => continue,
2240 else => |e| return e,
2241 };
2242 return try lib_directory.join(arena, &.{name});
2243 }
2244 return null;
2245}
2246
2247pub fn flushModule(
2248 coff: *Coff,1574 coff: *Coff,
2249 arena: Allocator,1575 arena: Allocator,
2250 tid: Zcu.PerThread.Id,1576 tid: Zcu.PerThread.Id,
...@@ -2256,22 +1582,22 @@ pub fn flushModule(...@@ -2256,22 +1582,22 @@ pub fn flushModule(
2256 const comp = coff.base.comp;1582 const comp = coff.base.comp;
2257 const diags = &comp.link_diags;1583 const diags = &comp.link_diags;
22581584
2259 if (coff.llvm_object) |llvm_object| {1585 switch (coff.base.comp.config.output_mode) {
2260 try coff.base.emitLlvmObject(arena, llvm_object, prog_node);1586 .Exe, .Obj => {},
2261 return;1587 .Lib => return diags.fail("writing lib files not yet implemented for COFF", .{}),
2262 }1588 }
22631589
2264 const sub_prog_node = prog_node.start("COFF Flush", 0);1590 const sub_prog_node = prog_node.start("COFF Flush", 0);
2265 defer sub_prog_node.end();1591 defer sub_prog_node.end();
22661592
2267 return flushModuleInner(coff, arena, tid) catch |err| switch (err) {1593 return flushInner(coff, arena, tid) catch |err| switch (err) {
2268 error.OutOfMemory => return error.OutOfMemory,1594 error.OutOfMemory => return error.OutOfMemory,
2269 error.LinkFailure => return error.LinkFailure,1595 error.LinkFailure => return error.LinkFailure,
2270 else => |e| return diags.fail("COFF flush failed: {s}", .{@errorName(e)}),1596 else => |e| return diags.fail("COFF flush failed: {s}", .{@errorName(e)}),
2271 };1597 };
2272}1598}
22731599
2274fn flushModuleInner(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id) !void {1600fn flushInner(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id) !void {
2275 _ = arena;1601 _ = arena;
22761602
2277 const comp = coff.base.comp;1603 const comp = coff.base.comp;
...@@ -2397,7 +1723,6 @@ pub fn getNavVAddr(...@@ -2397,7 +1723,6 @@ pub fn getNavVAddr(
2397 nav_index: InternPool.Nav.Index,1723 nav_index: InternPool.Nav.Index,
2398 reloc_info: link.File.RelocInfo,1724 reloc_info: link.File.RelocInfo,
2399) !u64 {1725) !u64 {
2400 assert(coff.llvm_object == null);
2401 const zcu = pt.zcu;1726 const zcu = pt.zcu;
2402 const ip = &zcu.intern_pool;1727 const ip = &zcu.intern_pool;
2403 const nav = ip.getNav(nav_index);1728 const nav = ip.getNav(nav_index);
...@@ -2442,7 +1767,7 @@ pub fn lowerUav(...@@ -2442,7 +1767,7 @@ pub fn lowerUav(
2442 const atom = coff.getAtom(metadata.atom);1767 const atom = coff.getAtom(metadata.atom);
2443 const existing_addr = atom.getSymbol(coff).value;1768 const existing_addr = atom.getSymbol(coff).value;
2444 if (uav_alignment.check(existing_addr))1769 if (uav_alignment.check(existing_addr))
2445 return .{ .mcv = .{ .load_direct = atom.getSymbolIndex().? } };1770 return .{ .mcv = .{ .load_symbol = atom.getSymbolIndex().? } };
2446 }1771 }
24471772
2448 var name_buf: [32]u8 = undefined;1773 var name_buf: [32]u8 = undefined;
...@@ -2474,7 +1799,7 @@ pub fn lowerUav(...@@ -2474,7 +1799,7 @@ pub fn lowerUav(
2474 .section = coff.rdata_section_index.?,1799 .section = coff.rdata_section_index.?,
2475 });1800 });
2476 return .{ .mcv = .{1801 return .{ .mcv = .{
2477 .load_direct = coff.getAtom(atom_index).getSymbolIndex().?,1802 .load_symbol = coff.getAtom(atom_index).getSymbolIndex().?,
2478 } };1803 } };
2479}1804}
24801805
...@@ -2483,8 +1808,6 @@ pub fn getUavVAddr(...@@ -2483,8 +1808,6 @@ pub fn getUavVAddr(
2483 uav: InternPool.Index,1808 uav: InternPool.Index,
2484 reloc_info: link.File.RelocInfo,1809 reloc_info: link.File.RelocInfo,
2485) !u64 {1810) !u64 {
2486 assert(coff.llvm_object == null);
2487
2488 const this_atom_index = coff.uavs.get(uav).?.atom;1811 const this_atom_index = coff.uavs.get(uav).?.atom;
2489 const sym_index = coff.getAtom(this_atom_index).getSymbolIndex().?;1812 const sym_index = coff.getAtom(this_atom_index).getSymbolIndex().?;
2490 const atom_index = coff.getAtomIndexForSymbol(.{1813 const atom_index = coff.getAtomIndexForSymbol(.{
...@@ -3796,9 +3119,7 @@ const link = @import("../link.zig");...@@ -3796,9 +3119,7 @@ const link = @import("../link.zig");
3796const target_util = @import("../target.zig");3119const target_util = @import("../target.zig");
3797const trace = @import("../tracy.zig").trace;3120const trace = @import("../tracy.zig").trace;
37983121
3799const Air = @import("../Air.zig");
3800const Compilation = @import("../Compilation.zig");3122const Compilation = @import("../Compilation.zig");
3801const LlvmObject = @import("../codegen/llvm.zig").Object;
3802const Zcu = @import("../Zcu.zig");3123const Zcu = @import("../Zcu.zig");
3803const InternPool = @import("../InternPool.zig");3124const InternPool = @import("../InternPool.zig");
3804const TableSection = @import("table_section.zig").TableSection;3125const TableSection = @import("table_section.zig").TableSection;
src/link/Dwarf.zig+204-23
...@@ -1474,24 +1474,59 @@ pub const WipNav = struct {...@@ -1474,24 +1474,59 @@ pub const WipNav = struct {
1474 try cfa.write(wip_nav);1474 try cfa.write(wip_nav);
1475 }1475 }
14761476
1477 pub const LocalTag = enum { local_arg, local_var };1477 pub const LocalVarTag = enum { arg, local_var };
1478 pub fn genLocalDebugInfo(1478 pub fn genLocalVarDebugInfo(
1479 wip_nav: *WipNav,1479 wip_nav: *WipNav,
1480 tag: LocalTag,1480 tag: LocalVarTag,
1481 name: []const u8,1481 opt_name: ?[]const u8,
1482 ty: Type,1482 ty: Type,
1483 loc: Loc,1483 loc: Loc,
1484 ) UpdateError!void {1484 ) UpdateError!void {
1485 assert(wip_nav.func != .none);1485 assert(wip_nav.func != .none);
1486 try wip_nav.abbrevCode(switch (tag) {1486 try wip_nav.abbrevCode(switch (tag) {
1487 inline else => |ct_tag| @field(AbbrevCode, @tagName(ct_tag)),1487 .arg => if (opt_name) |_| .arg else .unnamed_arg,
1488 .local_var => if (opt_name) |_| .local_var else unreachable,
1488 });1489 });
1489 try wip_nav.strp(name);1490 if (opt_name) |name| try wip_nav.strp(name);
1490 try wip_nav.refType(ty);1491 try wip_nav.refType(ty);
1491 try wip_nav.infoExprLoc(loc);1492 try wip_nav.infoExprLoc(loc);
1492 wip_nav.any_children = true;1493 wip_nav.any_children = true;
1493 }1494 }
14941495
1496 pub const LocalConstTag = enum { comptime_arg, local_const };
1497 pub fn genLocalConstDebugInfo(
1498 wip_nav: *WipNav,
1499 src_loc: Zcu.LazySrcLoc,
1500 tag: LocalConstTag,
1501 opt_name: ?[]const u8,
1502 val: Value,
1503 ) UpdateError!void {
1504 assert(wip_nav.func != .none);
1505 const pt = wip_nav.pt;
1506 const zcu = pt.zcu;
1507 const ty = val.typeOf(zcu);
1508 const has_runtime_bits = ty.hasRuntimeBits(zcu);
1509 const has_comptime_state = ty.comptimeOnly(zcu) and try ty.onePossibleValue(pt) == null;
1510 try wip_nav.abbrevCode(if (has_runtime_bits and has_comptime_state) switch (tag) {
1511 .comptime_arg => if (opt_name) |_| .comptime_arg_runtime_bits_comptime_state else .unnamed_comptime_arg_runtime_bits_comptime_state,
1512 .local_const => if (opt_name) |_| .local_const_runtime_bits_comptime_state else unreachable,
1513 } else if (has_comptime_state) switch (tag) {
1514 .comptime_arg => if (opt_name) |_| .comptime_arg_comptime_state else .unnamed_comptime_arg_comptime_state,
1515 .local_const => if (opt_name) |_| .local_const_comptime_state else unreachable,
1516 } else if (has_runtime_bits) switch (tag) {
1517 .comptime_arg => if (opt_name) |_| .comptime_arg_runtime_bits else .unnamed_comptime_arg_runtime_bits,
1518 .local_const => if (opt_name) |_| .local_const_runtime_bits else unreachable,
1519 } else switch (tag) {
1520 .comptime_arg => if (opt_name) |_| .comptime_arg else .unnamed_comptime_arg,
1521 .local_const => if (opt_name) |_| .local_const else unreachable,
1522 });
1523 if (opt_name) |name| try wip_nav.strp(name);
1524 try wip_nav.refType(ty);
1525 if (has_runtime_bits) try wip_nav.blockValue(src_loc, val);
1526 if (has_comptime_state) try wip_nav.refValue(val);
1527 wip_nav.any_children = true;
1528 }
1529
1495 pub fn genVarArgsDebugInfo(wip_nav: *WipNav) UpdateError!void {1530 pub fn genVarArgsDebugInfo(wip_nav: *WipNav) UpdateError!void {
1496 assert(wip_nav.func != .none);1531 assert(wip_nav.func != .none);
1497 try wip_nav.abbrevCode(.is_var_args);1532 try wip_nav.abbrevCode(.is_var_args);
...@@ -1825,7 +1860,8 @@ pub const WipNav = struct {...@@ -1825,7 +1860,8 @@ pub const WipNav = struct {
1825 fn getNavEntry(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!struct { Unit.Index, Entry.Index } {1860 fn getNavEntry(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!struct { Unit.Index, Entry.Index } {
1826 const zcu = wip_nav.pt.zcu;1861 const zcu = wip_nav.pt.zcu;
1827 const ip = &zcu.intern_pool;1862 const ip = &zcu.intern_pool;
1828 const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav_index).srcInst(ip).resolveFile(ip)).mod.?);1863 const nav = ip.getNav(nav_index);
1864 const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(nav.srcInst(ip).resolveFile(ip)).mod.?);
1829 const gop = try wip_nav.dwarf.navs.getOrPut(wip_nav.dwarf.gpa, nav_index);1865 const gop = try wip_nav.dwarf.navs.getOrPut(wip_nav.dwarf.gpa, nav_index);
1830 if (gop.found_existing) return .{ unit, gop.value_ptr.* };1866 if (gop.found_existing) return .{ unit, gop.value_ptr.* };
1831 const entry = try wip_nav.dwarf.addCommonEntry(unit);1867 const entry = try wip_nav.dwarf.addCommonEntry(unit);
...@@ -1842,10 +1878,16 @@ pub const WipNav = struct {...@@ -1842,10 +1878,16 @@ pub const WipNav = struct {
1842 const zcu = wip_nav.pt.zcu;1878 const zcu = wip_nav.pt.zcu;
1843 const ip = &zcu.intern_pool;1879 const ip = &zcu.intern_pool;
1844 const maybe_inst_index = ty.typeDeclInst(zcu);1880 const maybe_inst_index = ty.typeDeclInst(zcu);
1845 const unit = if (maybe_inst_index) |inst_index|1881 const unit = if (maybe_inst_index) |inst_index| switch (switch (ip.indexToKey(ty.toIntern())) {
1846 try wip_nav.dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?)1882 else => unreachable,
1847 else1883 .struct_type => ip.loadStructType(ty.toIntern()).name_nav,
1848 .main;1884 .union_type => ip.loadUnionType(ty.toIntern()).name_nav,
1885 .enum_type => ip.loadEnumType(ty.toIntern()).name_nav,
1886 .opaque_type => ip.loadOpaqueType(ty.toIntern()).name_nav,
1887 }) {
1888 .none => try wip_nav.dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?),
1889 else => |name_nav| return wip_nav.getNavEntry(name_nav.unwrap().?),
1890 } else .main;
1849 const gop = try wip_nav.dwarf.types.getOrPut(wip_nav.dwarf.gpa, ty.toIntern());1891 const gop = try wip_nav.dwarf.types.getOrPut(wip_nav.dwarf.gpa, ty.toIntern());
1850 if (gop.found_existing) return .{ unit, gop.value_ptr.* };1892 if (gop.found_existing) return .{ unit, gop.value_ptr.* };
1851 const entry = try wip_nav.dwarf.addCommonEntry(unit);1893 const entry = try wip_nav.dwarf.addCommonEntry(unit);
...@@ -1864,10 +1906,8 @@ pub const WipNav = struct {...@@ -1864,10 +1906,8 @@ pub const WipNav = struct {
1864 const ip = &zcu.intern_pool;1906 const ip = &zcu.intern_pool;
1865 const ty = value.typeOf(zcu);1907 const ty = value.typeOf(zcu);
1866 if (std.debug.runtime_safety) assert(ty.comptimeOnly(zcu) and try ty.onePossibleValue(wip_nav.pt) == null);1908 if (std.debug.runtime_safety) assert(ty.comptimeOnly(zcu) and try ty.onePossibleValue(wip_nav.pt) == null);
1867 if (!value.isUndef(zcu)) {1909 if (ty.toIntern() == .type_type) return wip_nav.getTypeEntry(value.toType());
1868 if (ty.toIntern() == .type_type) return wip_nav.getTypeEntry(value.toType());1910 if (ip.isFunctionType(ty.toIntern()) and !value.isUndef(zcu)) return wip_nav.getNavEntry(zcu.funcInfo(value.toIntern()).owner_nav);
1869 if (ip.isFunctionType(ty.toIntern())) return wip_nav.getNavEntry(zcu.funcInfo(value.toIntern()).owner_nav);
1870 }
1871 const gop = try wip_nav.dwarf.values.getOrPut(wip_nav.dwarf.gpa, value.toIntern());1911 const gop = try wip_nav.dwarf.values.getOrPut(wip_nav.dwarf.gpa, value.toIntern());
1872 const unit: Unit.Index = .main;1912 const unit: Unit.Index = .main;
1873 if (gop.found_existing) return .{ unit, gop.value_ptr.* };1913 if (gop.found_existing) return .{ unit, gop.value_ptr.* };
...@@ -1916,7 +1956,10 @@ pub const WipNav = struct {...@@ -1916,7 +1956,10 @@ pub const WipNav = struct {
1916 &wip_nav.debug_info,1956 &wip_nav.debug_info,
1917 .{ .debug_output = .{ .dwarf = wip_nav } },1957 .{ .debug_output = .{ .dwarf = wip_nav } },
1918 );1958 );
1919 assert(old_len + bytes == wip_nav.debug_info.items.len);1959 if (old_len + bytes != wip_nav.debug_info.items.len) {
1960 std.debug.print("{} [{}]: {} != {}\n", .{ ty.fmt(wip_nav.pt), ty.toIntern(), bytes, wip_nav.debug_info.items.len - old_len });
1961 unreachable;
1962 }
1920 }1963 }
19211964
1922 const AbbrevCodeForForm = struct {1965 const AbbrevCodeForForm = struct {
...@@ -2788,6 +2831,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -2788,6 +2831,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
2788 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());2831 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
2789 if (type_gop.found_existing) {2832 if (type_gop.found_existing) {
2790 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;2833 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
2834 assert(!nav_gop.found_existing);
2791 nav_gop.value_ptr.* = type_gop.value_ptr.*;2835 nav_gop.value_ptr.* = type_gop.value_ptr.*;
2792 } else {2836 } else {
2793 if (nav_gop.found_existing)2837 if (nav_gop.found_existing)
...@@ -2890,6 +2934,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -2890,6 +2934,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
2890 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());2934 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
2891 if (type_gop.found_existing) {2935 if (type_gop.found_existing) {
2892 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;2936 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
2937 assert(!nav_gop.found_existing);
2893 nav_gop.value_ptr.* = type_gop.value_ptr.*;2938 nav_gop.value_ptr.* = type_gop.value_ptr.*;
2894 } else {2939 } else {
2895 if (nav_gop.found_existing)2940 if (nav_gop.found_existing)
...@@ -2928,6 +2973,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -2928,6 +2973,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
2928 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());2973 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
2929 if (type_gop.found_existing) {2974 if (type_gop.found_existing) {
2930 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;2975 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
2976 assert(!nav_gop.found_existing);
2931 nav_gop.value_ptr.* = type_gop.value_ptr.*;2977 nav_gop.value_ptr.* = type_gop.value_ptr.*;
2932 } else {2978 } else {
2933 if (nav_gop.found_existing)2979 if (nav_gop.found_existing)
...@@ -2998,6 +3044,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -2998,6 +3044,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
2998 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());3044 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
2999 if (type_gop.found_existing) {3045 if (type_gop.found_existing) {
3000 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;3046 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
3047 assert(!nav_gop.found_existing);
3001 nav_gop.value_ptr.* = type_gop.value_ptr.*;3048 nav_gop.value_ptr.* = type_gop.value_ptr.*;
3002 } else {3049 } else {
3003 if (nav_gop.found_existing)3050 if (nav_gop.found_existing)
...@@ -3164,6 +3211,7 @@ fn updateLazyType(...@@ -3164,6 +3211,7 @@ fn updateLazyType(
3164) UpdateError!void {3211) UpdateError!void {
3165 const zcu = pt.zcu;3212 const zcu = pt.zcu;
3166 const ip = &zcu.intern_pool;3213 const ip = &zcu.intern_pool;
3214 assert(ip.typeOf(type_index) == .type_type);
3167 const ty: Type = .fromInterned(type_index);3215 const ty: Type = .fromInterned(type_index);
3168 switch (type_index) {3216 switch (type_index) {
3169 .generic_poison_type => log.debug("updateLazyType({s})", .{"anytype"}),3217 .generic_poison_type => log.debug("updateLazyType({s})", .{"anytype"}),
...@@ -3200,6 +3248,10 @@ fn updateLazyType(...@@ -3200,6 +3248,10 @@ fn updateLazyType(
3200 defer dwarf.gpa.free(name);3248 defer dwarf.gpa.free(name);
32013249
3202 switch (ip.indexToKey(type_index)) {3250 switch (ip.indexToKey(type_index)) {
3251 .undef => {
3252 try wip_nav.abbrevCode(.undefined_comptime_value);
3253 try wip_nav.refType(.type);
3254 },
3203 .int_type => |int_type| {3255 .int_type => |int_type| {
3204 try wip_nav.abbrevCode(.numeric_type);3256 try wip_nav.abbrevCode(.numeric_type);
3205 try wip_nav.strp(name);3257 try wip_nav.strp(name);
...@@ -3633,7 +3685,6 @@ fn updateLazyType(...@@ -3633,7 +3685,6 @@ fn updateLazyType(
3633 },3685 },
36343686
3635 // values, not types3687 // values, not types
3636 .undef,
3637 .simple_value,3688 .simple_value,
3638 .variable,3689 .variable,
3639 .@"extern",3690 .@"extern",
...@@ -3666,7 +3717,11 @@ fn updateLazyValue(...@@ -3666,7 +3717,11 @@ fn updateLazyValue(
3666) UpdateError!void {3717) UpdateError!void {
3667 const zcu = pt.zcu;3718 const zcu = pt.zcu;
3668 const ip = &zcu.intern_pool;3719 const ip = &zcu.intern_pool;
3669 log.debug("updateLazyValue({})", .{Value.fromInterned(value_index).fmtValue(pt)});3720 assert(ip.typeOf(value_index) != .type_type);
3721 log.debug("updateLazyValue(@as({}, {}))", .{
3722 Value.fromInterned(value_index).typeOf(zcu).fmt(pt),
3723 Value.fromInterned(value_index).fmtValue(pt),
3724 });
3670 var wip_nav: WipNav = .{3725 var wip_nav: WipNav = .{
3671 .dwarf = dwarf,3726 .dwarf = dwarf,
3672 .pt = pt,3727 .pt = pt,
...@@ -3710,9 +3765,8 @@ fn updateLazyValue(...@@ -3710,9 +3765,8 @@ fn updateLazyValue(
3710 .inferred_error_set_type,3765 .inferred_error_set_type,
3711 => unreachable, // already handled3766 => unreachable, // already handled
3712 .undef => |ty| {3767 .undef => |ty| {
3713 try wip_nav.abbrevCode(.aggregate_comptime_value);3768 try wip_nav.abbrevCode(.undefined_comptime_value);
3714 try wip_nav.refType(.fromInterned(ty));3769 try wip_nav.refType(.fromInterned(ty));
3715 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3716 },3770 },
3717 .simple_value => unreachable, // opv state3771 .simple_value => unreachable, // opv state
3718 .variable, .@"extern" => unreachable, // not a value3772 .variable, .@"extern" => unreachable, // not a value
...@@ -4391,7 +4445,7 @@ fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(A...@@ -4391,7 +4445,7 @@ fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(A
4391 return @intFromEnum(abbrev_code);4445 return @intFromEnum(abbrev_code);
4392}4446}
43934447
4394pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {4448pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
4395 const zcu = pt.zcu;4449 const zcu = pt.zcu;
4396 const ip = &zcu.intern_pool;4450 const ip = &zcu.intern_pool;
43974451
...@@ -4890,8 +4944,22 @@ const AbbrevCode = enum {...@@ -4890,8 +4944,22 @@ const AbbrevCode = enum {
4890 block,4944 block,
4891 empty_inlined_func,4945 empty_inlined_func,
4892 inlined_func,4946 inlined_func,
4893 local_arg,4947 arg,
4948 unnamed_arg,
4949 comptime_arg,
4950 unnamed_comptime_arg,
4951 comptime_arg_runtime_bits,
4952 unnamed_comptime_arg_runtime_bits,
4953 comptime_arg_comptime_state,
4954 unnamed_comptime_arg_comptime_state,
4955 comptime_arg_runtime_bits_comptime_state,
4956 unnamed_comptime_arg_runtime_bits_comptime_state,
4894 local_var,4957 local_var,
4958 local_const,
4959 local_const_runtime_bits,
4960 local_const_comptime_state,
4961 local_const_runtime_bits_comptime_state,
4962 undefined_comptime_value,
4895 data2_comptime_value,4963 data2_comptime_value,
4896 data4_comptime_value,4964 data4_comptime_value,
4897 data8_comptime_value,4965 data8_comptime_value,
...@@ -5663,7 +5731,7 @@ const AbbrevCode = enum {...@@ -5663,7 +5731,7 @@ const AbbrevCode = enum {
5663 .{ .high_pc, .data4 },5731 .{ .high_pc, .data4 },
5664 },5732 },
5665 },5733 },
5666 .local_arg = .{5734 .arg = .{
5667 .tag = .formal_parameter,5735 .tag = .formal_parameter,
5668 .attrs = &.{5736 .attrs = &.{
5669 .{ .name, .strp },5737 .{ .name, .strp },
...@@ -5671,6 +5739,81 @@ const AbbrevCode = enum {...@@ -5671,6 +5739,81 @@ const AbbrevCode = enum {
5671 .{ .location, .exprloc },5739 .{ .location, .exprloc },
5672 },5740 },
5673 },5741 },
5742 .unnamed_arg = .{
5743 .tag = .formal_parameter,
5744 .attrs = &.{
5745 .{ .type, .ref_addr },
5746 .{ .location, .exprloc },
5747 },
5748 },
5749 .comptime_arg = .{
5750 .tag = .formal_parameter,
5751 .attrs = &.{
5752 .{ .const_expr, .flag_present },
5753 .{ .name, .strp },
5754 .{ .type, .ref_addr },
5755 },
5756 },
5757 .unnamed_comptime_arg = .{
5758 .tag = .formal_parameter,
5759 .attrs = &.{
5760 .{ .const_expr, .flag_present },
5761 .{ .type, .ref_addr },
5762 },
5763 },
5764 .comptime_arg_runtime_bits = .{
5765 .tag = .formal_parameter,
5766 .attrs = &.{
5767 .{ .const_expr, .flag_present },
5768 .{ .name, .strp },
5769 .{ .type, .ref_addr },
5770 .{ .const_value, .block },
5771 },
5772 },
5773 .unnamed_comptime_arg_runtime_bits = .{
5774 .tag = .formal_parameter,
5775 .attrs = &.{
5776 .{ .const_expr, .flag_present },
5777 .{ .type, .ref_addr },
5778 .{ .const_value, .block },
5779 },
5780 },
5781 .comptime_arg_comptime_state = .{
5782 .tag = .formal_parameter,
5783 .attrs = &.{
5784 .{ .const_expr, .flag_present },
5785 .{ .name, .strp },
5786 .{ .type, .ref_addr },
5787 .{ .ZIG_comptime_value, .ref_addr },
5788 },
5789 },
5790 .unnamed_comptime_arg_comptime_state = .{
5791 .tag = .formal_parameter,
5792 .attrs = &.{
5793 .{ .const_expr, .flag_present },
5794 .{ .type, .ref_addr },
5795 .{ .ZIG_comptime_value, .ref_addr },
5796 },
5797 },
5798 .comptime_arg_runtime_bits_comptime_state = .{
5799 .tag = .formal_parameter,
5800 .attrs = &.{
5801 .{ .const_expr, .flag_present },
5802 .{ .name, .strp },
5803 .{ .type, .ref_addr },
5804 .{ .const_value, .block },
5805 .{ .ZIG_comptime_value, .ref_addr },
5806 },
5807 },
5808 .unnamed_comptime_arg_runtime_bits_comptime_state = .{
5809 .tag = .formal_parameter,
5810 .attrs = &.{
5811 .{ .const_expr, .flag_present },
5812 .{ .type, .ref_addr },
5813 .{ .const_value, .block },
5814 .{ .ZIG_comptime_value, .ref_addr },
5815 },
5816 },
5674 .local_var = .{5817 .local_var = .{
5675 .tag = .variable,5818 .tag = .variable,
5676 .attrs = &.{5819 .attrs = &.{
...@@ -5679,6 +5822,44 @@ const AbbrevCode = enum {...@@ -5679,6 +5822,44 @@ const AbbrevCode = enum {
5679 .{ .location, .exprloc },5822 .{ .location, .exprloc },
5680 },5823 },
5681 },5824 },
5825 .local_const = .{
5826 .tag = .constant,
5827 .attrs = &.{
5828 .{ .name, .strp },
5829 .{ .type, .ref_addr },
5830 },
5831 },
5832 .local_const_runtime_bits = .{
5833 .tag = .constant,
5834 .attrs = &.{
5835 .{ .name, .strp },
5836 .{ .type, .ref_addr },
5837 .{ .const_value, .block },
5838 },
5839 },
5840 .local_const_comptime_state = .{
5841 .tag = .constant,
5842 .attrs = &.{
5843 .{ .name, .strp },
5844 .{ .type, .ref_addr },
5845 .{ .ZIG_comptime_value, .ref_addr },
5846 },
5847 },
5848 .local_const_runtime_bits_comptime_state = .{
5849 .tag = .constant,
5850 .attrs = &.{
5851 .{ .name, .strp },
5852 .{ .type, .ref_addr },
5853 .{ .const_value, .block },
5854 .{ .ZIG_comptime_value, .ref_addr },
5855 },
5856 },
5857 .undefined_comptime_value = .{
5858 .tag = .ZIG_comptime_value,
5859 .attrs = &.{
5860 .{ .type, .ref_addr },
5861 },
5862 },
5682 .data2_comptime_value = .{5863 .data2_comptime_value = .{
5683 .tag = .ZIG_comptime_value,5864 .tag = .ZIG_comptime_value,
5684 .attrs = &.{5865 .attrs = &.{
src/link/Elf.zig+13-815
...@@ -4,7 +4,6 @@ base: link.File,...@@ -4,7 +4,6 @@ base: link.File,
4zig_object: ?*ZigObject,4zig_object: ?*ZigObject,
5rpath_table: std.StringArrayHashMapUnmanaged(void),5rpath_table: std.StringArrayHashMapUnmanaged(void),
6image_base: u64,6image_base: u64,
7emit_relocs: bool,
8z_nodelete: bool,7z_nodelete: bool,
9z_notext: bool,8z_notext: bool,
10z_defs: bool,9z_defs: bool,
...@@ -16,25 +15,11 @@ z_relro: bool,...@@ -16,25 +15,11 @@ z_relro: bool,
16z_common_page_size: ?u64,15z_common_page_size: ?u64,
17/// TODO make this non optional and resolve the default in open()16/// TODO make this non optional and resolve the default in open()
18z_max_page_size: ?u64,17z_max_page_size: ?u64,
19hash_style: HashStyle,
20compress_debug_sections: CompressDebugSections,
21symbol_wrap_set: std.StringArrayHashMapUnmanaged(void),
22sort_section: ?SortSection,
23soname: ?[]const u8,18soname: ?[]const u8,
24bind_global_refs_locally: bool,
25linker_script: ?[]const u8,
26version_script: ?[]const u8,
27allow_undefined_version: bool,
28enable_new_dtags: ?bool,
29print_icf_sections: bool,
30print_map: bool,
31entry_name: ?[]const u8,19entry_name: ?[]const u8,
3220
33ptr_width: PtrWidth,21ptr_width: PtrWidth,
3422
35/// If this is not null, an object file is created by LLVM and emitted to zcu_object_sub_path.
36llvm_object: ?LlvmObject.Ptr = null,
37
38/// A list of all input files.23/// A list of all input files.
39/// First index is a special "null file". Order is otherwise not observed.24/// First index is a special "null file". Order is otherwise not observed.
40files: std.MultiArrayList(File.Entry) = .{},25files: std.MultiArrayList(File.Entry) = .{},
...@@ -204,9 +189,6 @@ const minimum_atom_size = 64;...@@ -204,9 +189,6 @@ const minimum_atom_size = 64;
204pub const min_text_capacity = padToIdeal(minimum_atom_size);189pub const min_text_capacity = padToIdeal(minimum_atom_size);
205190
206pub const PtrWidth = enum { p32, p64 };191pub const PtrWidth = enum { p32, p64 };
207pub const HashStyle = enum { sysv, gnu, both };
208pub const CompressDebugSections = enum { none, zlib, zstd };
209pub const SortSection = enum { name, alignment };
210192
211pub fn createEmpty(193pub fn createEmpty(
212 arena: Allocator,194 arena: Allocator,
...@@ -217,7 +199,6 @@ pub fn createEmpty(...@@ -217,7 +199,6 @@ pub fn createEmpty(
217 const target = comp.root_mod.resolved_target.result;199 const target = comp.root_mod.resolved_target.result;
218 assert(target.ofmt == .elf);200 assert(target.ofmt == .elf);
219201
220 const use_lld = build_options.have_llvm and comp.config.use_lld;
221 const use_llvm = comp.config.use_llvm;202 const use_llvm = comp.config.use_llvm;
222 const opt_zcu = comp.zcu;203 const opt_zcu = comp.zcu;
223 const output_mode = comp.config.output_mode;204 const output_mode = comp.config.output_mode;
...@@ -268,16 +249,6 @@ pub fn createEmpty(...@@ -268,16 +249,6 @@ pub fn createEmpty(
268 const is_dyn_lib = output_mode == .Lib and link_mode == .dynamic;249 const is_dyn_lib = output_mode == .Lib and link_mode == .dynamic;
269 const default_sym_version: elf.Versym = if (is_dyn_lib or comp.config.rdynamic) .GLOBAL else .LOCAL;250 const default_sym_version: elf.Versym = if (is_dyn_lib or comp.config.rdynamic) .GLOBAL else .LOCAL;
270251
271 // If using LLD to link, this code should produce an object file so that it
272 // can be passed to LLD.
273 // If using LLVM to generate the object file for the zig compilation unit,
274 // we need a place to put the object file so that it can be subsequently
275 // handled.
276 const zcu_object_sub_path = if (!use_lld and !use_llvm)
277 null
278 else
279 try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path});
280
281 var rpath_table: std.StringArrayHashMapUnmanaged(void) = .empty;252 var rpath_table: std.StringArrayHashMapUnmanaged(void) = .empty;
282 try rpath_table.entries.resize(arena, options.rpath_list.len);253 try rpath_table.entries.resize(arena, options.rpath_list.len);
283 @memcpy(rpath_table.entries.items(.key), options.rpath_list);254 @memcpy(rpath_table.entries.items(.key), options.rpath_list);
...@@ -289,13 +260,15 @@ pub fn createEmpty(...@@ -289,13 +260,15 @@ pub fn createEmpty(
289 .tag = .elf,260 .tag = .elf,
290 .comp = comp,261 .comp = comp,
291 .emit = emit,262 .emit = emit,
292 .zcu_object_sub_path = zcu_object_sub_path,263 .zcu_object_basename = if (use_llvm)
264 try std.fmt.allocPrint(arena, "{s}_zcu.o", .{fs.path.stem(emit.sub_path)})
265 else
266 null,
293 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj),267 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj),
294 .print_gc_sections = options.print_gc_sections,268 .print_gc_sections = options.print_gc_sections,
295 .stack_size = options.stack_size orelse 16777216,269 .stack_size = options.stack_size orelse 16777216,
296 .allow_shlib_undefined = options.allow_shlib_undefined orelse !is_native_os,270 .allow_shlib_undefined = options.allow_shlib_undefined orelse !is_native_os,
297 .file = null,271 .file = null,
298 .disable_lld_caching = options.disable_lld_caching,
299 .build_id = options.build_id,272 .build_id = options.build_id,
300 },273 },
301 .zig_object = null,274 .zig_object = null,
...@@ -320,7 +293,6 @@ pub fn createEmpty(...@@ -320,7 +293,6 @@ pub fn createEmpty(
320 };293 };
321 },294 },
322295
323 .emit_relocs = options.emit_relocs,
324 .z_nodelete = options.z_nodelete,296 .z_nodelete = options.z_nodelete,
325 .z_notext = options.z_notext,297 .z_notext = options.z_notext,
326 .z_defs = options.z_defs,298 .z_defs = options.z_defs,
...@@ -330,30 +302,11 @@ pub fn createEmpty(...@@ -330,30 +302,11 @@ pub fn createEmpty(
330 .z_relro = options.z_relro,302 .z_relro = options.z_relro,
331 .z_common_page_size = options.z_common_page_size,303 .z_common_page_size = options.z_common_page_size,
332 .z_max_page_size = options.z_max_page_size,304 .z_max_page_size = options.z_max_page_size,
333 .hash_style = options.hash_style,
334 .compress_debug_sections = options.compress_debug_sections,
335 .symbol_wrap_set = options.symbol_wrap_set,
336 .sort_section = options.sort_section,
337 .soname = options.soname,305 .soname = options.soname,
338 .bind_global_refs_locally = options.bind_global_refs_locally,
339 .linker_script = options.linker_script,
340 .version_script = options.version_script,
341 .allow_undefined_version = options.allow_undefined_version,
342 .enable_new_dtags = options.enable_new_dtags,
343 .print_icf_sections = options.print_icf_sections,
344 .print_map = options.print_map,
345 .dump_argv_list = .empty,306 .dump_argv_list = .empty,
346 };307 };
347 if (use_llvm and comp.config.have_zcu) {
348 self.llvm_object = try LlvmObject.create(arena, comp);
349 }
350 errdefer self.base.destroy();308 errdefer self.base.destroy();
351309
352 if (use_lld and (use_llvm or !comp.config.have_zcu)) {
353 // LLVM emits the object file (if any); LLD links it into the final product.
354 return self;
355 }
356
357 // --verbose-link310 // --verbose-link
358 if (comp.verbose_link) try dumpArgvInit(self, arena);311 if (comp.verbose_link) try dumpArgvInit(self, arena);
359312
...@@ -361,13 +314,11 @@ pub fn createEmpty(...@@ -361,13 +314,11 @@ pub fn createEmpty(
361 const is_obj_or_ar = is_obj or (output_mode == .Lib and link_mode == .static);314 const is_obj_or_ar = is_obj or (output_mode == .Lib and link_mode == .static);
362315
363 // What path should this ELF linker code output to?316 // What path should this ELF linker code output to?
364 // If using LLD to link, this code should produce an object file so that it317 const sub_path = emit.sub_path;
365 // can be passed to LLD.
366 const sub_path = if (use_lld) zcu_object_sub_path.? else emit.sub_path;
367 self.base.file = try emit.root_dir.handle.createFile(sub_path, .{318 self.base.file = try emit.root_dir.handle.createFile(sub_path, .{
368 .truncate = true,319 .truncate = true,
369 .read = true,320 .read = true,
370 .mode = link.File.determineMode(use_lld, output_mode, link_mode),321 .mode = link.File.determineMode(output_mode, link_mode),
371 });322 });
372323
373 const gpa = comp.gpa;324 const gpa = comp.gpa;
...@@ -457,8 +408,6 @@ pub fn open(...@@ -457,8 +408,6 @@ pub fn open(
457pub fn deinit(self: *Elf) void {408pub fn deinit(self: *Elf) void {
458 const gpa = self.base.comp.gpa;409 const gpa = self.base.comp.gpa;
459410
460 if (self.llvm_object) |llvm_object| llvm_object.deinit();
461
462 for (self.file_handles.items) |fh| {411 for (self.file_handles.items) |fh| {
463 fh.close();412 fh.close();
464 }413 }
...@@ -515,7 +464,6 @@ pub fn deinit(self: *Elf) void {...@@ -515,7 +464,6 @@ pub fn deinit(self: *Elf) void {
515}464}
516465
517pub fn getNavVAddr(self: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {466pub fn getNavVAddr(self: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {
518 assert(self.llvm_object == null);
519 return self.zigObjectPtr().?.getNavVAddr(self, pt, nav_index, reloc_info);467 return self.zigObjectPtr().?.getNavVAddr(self, pt, nav_index, reloc_info);
520}468}
521469
...@@ -530,7 +478,6 @@ pub fn lowerUav(...@@ -530,7 +478,6 @@ pub fn lowerUav(
530}478}
531479
532pub fn getUavVAddr(self: *Elf, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {480pub fn getUavVAddr(self: *Elf, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
533 assert(self.llvm_object == null);
534 return self.zigObjectPtr().?.getUavVAddr(self, uav, reloc_info);481 return self.zigObjectPtr().?.getUavVAddr(self, uav, reloc_info);
535}482}
536483
...@@ -795,60 +742,36 @@ pub fn loadInput(self: *Elf, input: link.Input) !void {...@@ -795,60 +742,36 @@ pub fn loadInput(self: *Elf, input: link.Input) !void {
795}742}
796743
797pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {744pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
798 const comp = self.base.comp;
799 const use_lld = build_options.have_llvm and comp.config.use_lld;
800 const diags = &comp.link_diags;
801 if (use_lld) {
802 return self.linkWithLLD(arena, tid, prog_node) catch |err| switch (err) {
803 error.OutOfMemory => return error.OutOfMemory,
804 error.LinkFailure => return error.LinkFailure,
805 else => |e| return diags.fail("failed to link with LLD: {s}", .{@errorName(e)}),
806 };
807 }
808 try self.flushModule(arena, tid, prog_node);
809}
810
811pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
812 const tracy = trace(@src());745 const tracy = trace(@src());
813 defer tracy.end();746 defer tracy.end();
814747
815 const comp = self.base.comp;748 const comp = self.base.comp;
816 const diags = &comp.link_diags;749 const diags = &comp.link_diags;
817750
818 if (self.llvm_object) |llvm_object| {
819 try self.base.emitLlvmObject(arena, llvm_object, prog_node);
820 const use_lld = build_options.have_llvm and comp.config.use_lld;
821 if (use_lld) return;
822 }
823
824 if (comp.verbose_link) Compilation.dump_argv(self.dump_argv_list.items);751 if (comp.verbose_link) Compilation.dump_argv(self.dump_argv_list.items);
825752
826 const sub_prog_node = prog_node.start("ELF Flush", 0);753 const sub_prog_node = prog_node.start("ELF Flush", 0);
827 defer sub_prog_node.end();754 defer sub_prog_node.end();
828755
829 return flushModuleInner(self, arena, tid) catch |err| switch (err) {756 return flushInner(self, arena, tid) catch |err| switch (err) {
830 error.OutOfMemory => return error.OutOfMemory,757 error.OutOfMemory => return error.OutOfMemory,
831 error.LinkFailure => return error.LinkFailure,758 error.LinkFailure => return error.LinkFailure,
832 else => |e| return diags.fail("ELF flush failed: {s}", .{@errorName(e)}),759 else => |e| return diags.fail("ELF flush failed: {s}", .{@errorName(e)}),
833 };760 };
834}761}
835762
836fn flushModuleInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void {763fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void {
837 const comp = self.base.comp;764 const comp = self.base.comp;
838 const gpa = comp.gpa;765 const gpa = comp.gpa;
839 const diags = &comp.link_diags;766 const diags = &comp.link_diags;
840767
841 const module_obj_path: ?Path = if (self.base.zcu_object_sub_path) |path| .{768 const zcu_obj_path: ?Path = if (self.base.zcu_object_basename) |raw| p: {
842 .root_dir = self.base.emit.root_dir,769 break :p try comp.resolveEmitPathFlush(arena, .temp, raw);
843 .sub_path = if (fs.path.dirname(self.base.emit.sub_path)) |dirname|
844 try fs.path.join(arena, &.{ dirname, path })
845 else
846 path,
847 } else null;770 } else null;
848771
849 if (self.zigObjectPtr()) |zig_object| try zig_object.flush(self, tid);772 if (self.zigObjectPtr()) |zig_object| try zig_object.flush(self, tid);
850773
851 if (module_obj_path) |path| openParseObjectReportingFailure(self, path);774 if (zcu_obj_path) |path| openParseObjectReportingFailure(self, path);
852775
853 switch (comp.config.output_mode) {776 switch (comp.config.output_mode) {
854 .Obj => return relocatable.flushObject(self, comp),777 .Obj => return relocatable.flushObject(self, comp),
...@@ -1508,639 +1431,6 @@ pub fn initOutputSection(self: *Elf, args: struct {...@@ -1508,639 +1431,6 @@ pub fn initOutputSection(self: *Elf, args: struct {
1508 return out_shndx;1431 return out_shndx;
1509}1432}
15101433
1511fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
1512 dev.check(.lld_linker);
1513
1514 const tracy = trace(@src());
1515 defer tracy.end();
1516
1517 const comp = self.base.comp;
1518 const gpa = comp.gpa;
1519 const diags = &comp.link_diags;
1520
1521 const directory = self.base.emit.root_dir; // Just an alias to make it shorter to type.
1522 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});
1523
1524 // If there is no Zig code to compile, then we should skip flushing the output file because it
1525 // will not be part of the linker line anyway.
1526 const module_obj_path: ?[]const u8 = if (comp.zcu != null) blk: {
1527 try self.flushModule(arena, tid, prog_node);
1528
1529 if (fs.path.dirname(full_out_path)) |dirname| {
1530 break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? });
1531 } else {
1532 break :blk self.base.zcu_object_sub_path.?;
1533 }
1534 } else null;
1535
1536 const sub_prog_node = prog_node.start("LLD Link", 0);
1537 defer sub_prog_node.end();
1538
1539 const output_mode = comp.config.output_mode;
1540 const is_obj = output_mode == .Obj;
1541 const is_lib = output_mode == .Lib;
1542 const link_mode = comp.config.link_mode;
1543 const is_dyn_lib = link_mode == .dynamic and is_lib;
1544 const is_exe_or_dyn_lib = is_dyn_lib or output_mode == .Exe;
1545 const have_dynamic_linker = link_mode == .dynamic and is_exe_or_dyn_lib;
1546 const target = self.getTarget();
1547 const compiler_rt_path: ?Path = blk: {
1548 if (comp.compiler_rt_lib) |x| break :blk x.full_object_path;
1549 if (comp.compiler_rt_obj) |x| break :blk x.full_object_path;
1550 break :blk null;
1551 };
1552 const ubsan_rt_path: ?Path = blk: {
1553 if (comp.ubsan_rt_lib) |x| break :blk x.full_object_path;
1554 if (comp.ubsan_rt_obj) |x| break :blk x.full_object_path;
1555 break :blk null;
1556 };
1557
1558 // Here we want to determine whether we can save time by not invoking LLD when the
1559 // output is unchanged. None of the linker options or the object files that are being
1560 // linked are in the hash that namespaces the directory we are outputting to. Therefore,
1561 // we must hash those now, and the resulting digest will form the "id" of the linking
1562 // job we are about to perform.
1563 // After a successful link, we store the id in the metadata of a symlink named "lld.id" in
1564 // the artifact directory. So, now, we check if this symlink exists, and if it matches
1565 // our digest. If so, we can skip linking. Otherwise, we proceed with invoking LLD.
1566 const id_symlink_basename = "lld.id";
1567
1568 var man: std.Build.Cache.Manifest = undefined;
1569 defer if (!self.base.disable_lld_caching) man.deinit();
1570
1571 var digest: [std.Build.Cache.hex_digest_len]u8 = undefined;
1572
1573 if (!self.base.disable_lld_caching) {
1574 man = comp.cache_parent.obtain();
1575
1576 // We are about to obtain this lock, so here we give other processes a chance first.
1577 self.base.releaseLock();
1578
1579 comptime assert(Compilation.link_hash_implementation_version == 14);
1580
1581 try man.addOptionalFile(self.linker_script);
1582 try man.addOptionalFile(self.version_script);
1583 man.hash.add(self.allow_undefined_version);
1584 man.hash.addOptional(self.enable_new_dtags);
1585 try link.hashInputs(&man, comp.link_inputs);
1586 for (comp.c_object_table.keys()) |key| {
1587 _ = try man.addFilePath(key.status.success.object_path, null);
1588 }
1589 try man.addOptionalFile(module_obj_path);
1590 try man.addOptionalFilePath(compiler_rt_path);
1591 try man.addOptionalFilePath(ubsan_rt_path);
1592 try man.addOptionalFilePath(if (comp.tsan_lib) |l| l.full_object_path else null);
1593 try man.addOptionalFilePath(if (comp.fuzzer_lib) |l| l.full_object_path else null);
1594
1595 // We can skip hashing libc and libc++ components that we are in charge of building from Zig
1596 // installation sources because they are always a product of the compiler version + target information.
1597 man.hash.addOptionalBytes(self.entry_name);
1598 man.hash.add(self.image_base);
1599 man.hash.add(self.base.gc_sections);
1600 man.hash.addOptional(self.sort_section);
1601 man.hash.add(comp.link_eh_frame_hdr);
1602 man.hash.add(self.emit_relocs);
1603 man.hash.add(comp.config.rdynamic);
1604 man.hash.addListOfBytes(self.rpath_table.keys());
1605 if (output_mode == .Exe) {
1606 man.hash.add(self.base.stack_size);
1607 }
1608 man.hash.add(self.base.build_id);
1609 man.hash.addListOfBytes(self.symbol_wrap_set.keys());
1610 man.hash.add(comp.skip_linker_dependencies);
1611 man.hash.add(self.z_nodelete);
1612 man.hash.add(self.z_notext);
1613 man.hash.add(self.z_defs);
1614 man.hash.add(self.z_origin);
1615 man.hash.add(self.z_nocopyreloc);
1616 man.hash.add(self.z_now);
1617 man.hash.add(self.z_relro);
1618 man.hash.add(self.z_common_page_size orelse 0);
1619 man.hash.add(self.z_max_page_size orelse 0);
1620 man.hash.add(self.hash_style);
1621 // strip does not need to go into the linker hash because it is part of the hash namespace
1622 if (comp.config.link_libc) {
1623 man.hash.add(comp.libc_installation != null);
1624 if (comp.libc_installation) |libc_installation| {
1625 man.hash.addBytes(libc_installation.crt_dir.?);
1626 }
1627 }
1628 if (have_dynamic_linker) {
1629 man.hash.addOptionalBytes(target.dynamic_linker.get());
1630 }
1631 man.hash.addOptionalBytes(self.soname);
1632 man.hash.addOptional(comp.version);
1633 man.hash.addListOfBytes(comp.force_undefined_symbols.keys());
1634 man.hash.add(self.base.allow_shlib_undefined);
1635 man.hash.add(self.bind_global_refs_locally);
1636 man.hash.add(self.compress_debug_sections);
1637 man.hash.add(comp.config.any_sanitize_thread);
1638 man.hash.add(comp.config.any_fuzz);
1639 man.hash.addOptionalBytes(comp.sysroot);
1640
1641 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
1642 _ = try man.hit();
1643 digest = man.final();
1644
1645 var prev_digest_buf: [digest.len]u8 = undefined;
1646 const prev_digest: []u8 = std.Build.Cache.readSmallFile(
1647 directory.handle,
1648 id_symlink_basename,
1649 &prev_digest_buf,
1650 ) catch |err| blk: {
1651 log.debug("ELF LLD new_digest={s} error: {s}", .{ std.fmt.fmtSliceHexLower(&digest), @errorName(err) });
1652 // Handle this as a cache miss.
1653 break :blk prev_digest_buf[0..0];
1654 };
1655 if (mem.eql(u8, prev_digest, &digest)) {
1656 log.debug("ELF LLD digest={s} match - skipping invocation", .{std.fmt.fmtSliceHexLower(&digest)});
1657 // Hot diggity dog! The output binary is already there.
1658 self.base.lock = man.toOwnedLock();
1659 return;
1660 }
1661 log.debug("ELF LLD prev_digest={s} new_digest={s}", .{ std.fmt.fmtSliceHexLower(prev_digest), std.fmt.fmtSliceHexLower(&digest) });
1662
1663 // We are about to change the output file to be different, so we invalidate the build hash now.
1664 directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) {
1665 error.FileNotFound => {},
1666 else => |e| return e,
1667 };
1668 }
1669
1670 // Due to a deficiency in LLD, we need to special-case BPF to a simple file
1671 // copy when generating relocatables. Normally, we would expect `lld -r` to work.
1672 // However, because LLD wants to resolve BPF relocations which it shouldn't, it fails
1673 // before even generating the relocatable.
1674 //
1675 // For m68k, we go through this path because LLD doesn't support it yet, but LLVM can
1676 // produce usable object files.
1677 if (output_mode == .Obj and
1678 (comp.config.lto != .none or
1679 target.cpu.arch.isBpf() or
1680 target.cpu.arch == .lanai or
1681 target.cpu.arch == .m68k or
1682 target.cpu.arch.isSPARC() or
1683 target.cpu.arch == .ve or
1684 target.cpu.arch == .xcore))
1685 {
1686 // In this case we must do a simple file copy
1687 // here. TODO: think carefully about how we can avoid this redundant operation when doing
1688 // build-obj. See also the corresponding TODO in linkAsArchive.
1689 const the_object_path = blk: {
1690 if (link.firstObjectInput(comp.link_inputs)) |obj| break :blk obj.path;
1691
1692 if (comp.c_object_table.count() != 0)
1693 break :blk comp.c_object_table.keys()[0].status.success.object_path;
1694
1695 if (module_obj_path) |p|
1696 break :blk Path.initCwd(p);
1697
1698 // TODO I think this is unreachable. Audit this situation when solving the above TODO
1699 // regarding eliding redundant object -> object transformations.
1700 return error.NoObjectsToLink;
1701 };
1702 try std.fs.Dir.copyFile(
1703 the_object_path.root_dir.handle,
1704 the_object_path.sub_path,
1705 directory.handle,
1706 self.base.emit.sub_path,
1707 .{},
1708 );
1709 } else {
1710 // Create an LLD command line and invoke it.
1711 var argv = std.ArrayList([]const u8).init(gpa);
1712 defer argv.deinit();
1713 // We will invoke ourselves as a child process to gain access to LLD.
1714 // This is necessary because LLD does not behave properly as a library -
1715 // it calls exit() and does not reset all global data between invocations.
1716 const linker_command = "ld.lld";
1717 try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command });
1718 if (is_obj) {
1719 try argv.append("-r");
1720 }
1721
1722 try argv.append("--error-limit=0");
1723
1724 if (comp.sysroot) |sysroot| {
1725 try argv.append(try std.fmt.allocPrint(arena, "--sysroot={s}", .{sysroot}));
1726 }
1727
1728 if (target_util.llvmMachineAbi(target)) |mabi| {
1729 try argv.appendSlice(&.{
1730 "-mllvm",
1731 try std.fmt.allocPrint(arena, "-target-abi={s}", .{mabi}),
1732 });
1733 }
1734
1735 try argv.appendSlice(&.{
1736 "-mllvm",
1737 try std.fmt.allocPrint(arena, "-float-abi={s}", .{if (target.abi.float() == .hard) "hard" else "soft"}),
1738 });
1739
1740 if (comp.config.lto != .none) {
1741 switch (comp.root_mod.optimize_mode) {
1742 .Debug => {},
1743 .ReleaseSmall => try argv.append("--lto-O2"),
1744 .ReleaseFast, .ReleaseSafe => try argv.append("--lto-O3"),
1745 }
1746 }
1747 switch (comp.root_mod.optimize_mode) {
1748 .Debug => {},
1749 .ReleaseSmall => try argv.append("-O2"),
1750 .ReleaseFast, .ReleaseSafe => try argv.append("-O3"),
1751 }
1752
1753 if (self.entry_name) |name| {
1754 try argv.appendSlice(&.{ "--entry", name });
1755 }
1756
1757 for (comp.force_undefined_symbols.keys()) |sym| {
1758 try argv.append("-u");
1759 try argv.append(sym);
1760 }
1761
1762 switch (self.hash_style) {
1763 .gnu => try argv.append("--hash-style=gnu"),
1764 .sysv => try argv.append("--hash-style=sysv"),
1765 .both => {}, // this is the default
1766 }
1767
1768 if (output_mode == .Exe) {
1769 try argv.appendSlice(&.{
1770 "-z",
1771 try std.fmt.allocPrint(arena, "stack-size={d}", .{self.base.stack_size}),
1772 });
1773 }
1774
1775 switch (self.base.build_id) {
1776 .none => try argv.append("--build-id=none"),
1777 .fast, .uuid, .sha1, .md5 => try argv.append(try std.fmt.allocPrint(arena, "--build-id={s}", .{
1778 @tagName(self.base.build_id),
1779 })),
1780 .hexstring => |hs| try argv.append(try std.fmt.allocPrint(arena, "--build-id=0x{s}", .{
1781 std.fmt.fmtSliceHexLower(hs.toSlice()),
1782 })),
1783 }
1784
1785 try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{self.image_base}));
1786
1787 if (self.linker_script) |linker_script| {
1788 try argv.append("-T");
1789 try argv.append(linker_script);
1790 }
1791
1792 if (self.sort_section) |how| {
1793 const arg = try std.fmt.allocPrint(arena, "--sort-section={s}", .{@tagName(how)});
1794 try argv.append(arg);
1795 }
1796
1797 if (self.base.gc_sections) {
1798 try argv.append("--gc-sections");
1799 }
1800
1801 if (self.base.print_gc_sections) {
1802 try argv.append("--print-gc-sections");
1803 }
1804
1805 if (self.print_icf_sections) {
1806 try argv.append("--print-icf-sections");
1807 }
1808
1809 if (self.print_map) {
1810 try argv.append("--print-map");
1811 }
1812
1813 if (comp.link_eh_frame_hdr) {
1814 try argv.append("--eh-frame-hdr");
1815 }
1816
1817 if (self.emit_relocs) {
1818 try argv.append("--emit-relocs");
1819 }
1820
1821 if (comp.config.rdynamic) {
1822 try argv.append("--export-dynamic");
1823 }
1824
1825 if (comp.config.debug_format == .strip) {
1826 try argv.append("-s");
1827 }
1828
1829 if (self.z_nodelete) {
1830 try argv.append("-z");
1831 try argv.append("nodelete");
1832 }
1833 if (self.z_notext) {
1834 try argv.append("-z");
1835 try argv.append("notext");
1836 }
1837 if (self.z_defs) {
1838 try argv.append("-z");
1839 try argv.append("defs");
1840 }
1841 if (self.z_origin) {
1842 try argv.append("-z");
1843 try argv.append("origin");
1844 }
1845 if (self.z_nocopyreloc) {
1846 try argv.append("-z");
1847 try argv.append("nocopyreloc");
1848 }
1849 if (self.z_now) {
1850 // LLD defaults to -zlazy
1851 try argv.append("-znow");
1852 }
1853 if (!self.z_relro) {
1854 // LLD defaults to -zrelro
1855 try argv.append("-znorelro");
1856 }
1857 if (self.z_common_page_size) |size| {
1858 try argv.append("-z");
1859 try argv.append(try std.fmt.allocPrint(arena, "common-page-size={d}", .{size}));
1860 }
1861 if (self.z_max_page_size) |size| {
1862 try argv.append("-z");
1863 try argv.append(try std.fmt.allocPrint(arena, "max-page-size={d}", .{size}));
1864 }
1865
1866 if (getLDMOption(target)) |ldm| {
1867 try argv.append("-m");
1868 try argv.append(ldm);
1869 }
1870
1871 if (link_mode == .static) {
1872 if (target.cpu.arch.isArm()) {
1873 try argv.append("-Bstatic");
1874 } else {
1875 try argv.append("-static");
1876 }
1877 } else if (switch (target.os.tag) {
1878 else => is_dyn_lib,
1879 .haiku => is_exe_or_dyn_lib,
1880 }) {
1881 try argv.append("-shared");
1882 }
1883
1884 if (comp.config.pie and output_mode == .Exe) {
1885 try argv.append("-pie");
1886 }
1887
1888 if (is_exe_or_dyn_lib and target.os.tag == .netbsd) {
1889 // Add options to produce shared objects with only 2 PT_LOAD segments.
1890 // NetBSD expects 2 PT_LOAD segments in a shared object, otherwise
1891 // ld.elf_so fails loading dynamic libraries with "not found" error.
1892 // See https://github.com/ziglang/zig/issues/9109 .
1893 try argv.append("--no-rosegment");
1894 try argv.append("-znorelro");
1895 }
1896
1897 try argv.append("-o");
1898 try argv.append(full_out_path);
1899
1900 // csu prelude
1901 const csu = try comp.getCrtPaths(arena);
1902 if (csu.crt0) |p| try argv.append(try p.toString(arena));
1903 if (csu.crti) |p| try argv.append(try p.toString(arena));
1904 if (csu.crtbegin) |p| try argv.append(try p.toString(arena));
1905
1906 for (self.rpath_table.keys()) |rpath| {
1907 try argv.appendSlice(&.{ "-rpath", rpath });
1908 }
1909
1910 for (self.symbol_wrap_set.keys()) |symbol_name| {
1911 try argv.appendSlice(&.{ "-wrap", symbol_name });
1912 }
1913
1914 if (comp.config.link_libc) {
1915 if (comp.libc_installation) |libc_installation| {
1916 try argv.append("-L");
1917 try argv.append(libc_installation.crt_dir.?);
1918 }
1919 }
1920
1921 if (have_dynamic_linker and
1922 (comp.config.link_libc or comp.root_mod.resolved_target.is_explicit_dynamic_linker))
1923 {
1924 if (target.dynamic_linker.get()) |dynamic_linker| {
1925 try argv.append("-dynamic-linker");
1926 try argv.append(dynamic_linker);
1927 }
1928 }
1929
1930 if (is_dyn_lib) {
1931 if (self.soname) |soname| {
1932 try argv.append("-soname");
1933 try argv.append(soname);
1934 }
1935 if (self.version_script) |version_script| {
1936 try argv.append("-version-script");
1937 try argv.append(version_script);
1938 }
1939 if (self.allow_undefined_version) {
1940 try argv.append("--undefined-version");
1941 } else {
1942 try argv.append("--no-undefined-version");
1943 }
1944 if (self.enable_new_dtags) |enable_new_dtags| {
1945 if (enable_new_dtags) {
1946 try argv.append("--enable-new-dtags");
1947 } else {
1948 try argv.append("--disable-new-dtags");
1949 }
1950 }
1951 }
1952
1953 // Positional arguments to the linker such as object files.
1954 var whole_archive = false;
1955
1956 for (self.base.comp.link_inputs) |link_input| switch (link_input) {
1957 .res => unreachable, // Windows-only
1958 .dso => continue,
1959 .object, .archive => |obj| {
1960 if (obj.must_link and !whole_archive) {
1961 try argv.append("-whole-archive");
1962 whole_archive = true;
1963 } else if (!obj.must_link and whole_archive) {
1964 try argv.append("-no-whole-archive");
1965 whole_archive = false;
1966 }
1967 try argv.append(try obj.path.toString(arena));
1968 },
1969 .dso_exact => |dso_exact| {
1970 assert(dso_exact.name[0] == ':');
1971 try argv.appendSlice(&.{ "-l", dso_exact.name });
1972 },
1973 };
1974
1975 if (whole_archive) {
1976 try argv.append("-no-whole-archive");
1977 whole_archive = false;
1978 }
1979
1980 for (comp.c_object_table.keys()) |key| {
1981 try argv.append(try key.status.success.object_path.toString(arena));
1982 }
1983
1984 if (module_obj_path) |p| {
1985 try argv.append(p);
1986 }
1987
1988 if (comp.tsan_lib) |lib| {
1989 assert(comp.config.any_sanitize_thread);
1990 try argv.append(try lib.full_object_path.toString(arena));
1991 }
1992
1993 if (comp.fuzzer_lib) |lib| {
1994 assert(comp.config.any_fuzz);
1995 try argv.append(try lib.full_object_path.toString(arena));
1996 }
1997
1998 if (ubsan_rt_path) |p| {
1999 try argv.append(try p.toString(arena));
2000 }
2001
2002 // Shared libraries.
2003 if (is_exe_or_dyn_lib) {
2004 // Worst-case, we need an --as-needed argument for every lib, as well
2005 // as one before and one after.
2006 try argv.ensureUnusedCapacity(2 * self.base.comp.link_inputs.len + 2);
2007 argv.appendAssumeCapacity("--as-needed");
2008 var as_needed = true;
2009
2010 for (self.base.comp.link_inputs) |link_input| switch (link_input) {
2011 .res => unreachable, // Windows-only
2012 .object, .archive, .dso_exact => continue,
2013 .dso => |dso| {
2014 const lib_as_needed = !dso.needed;
2015 switch ((@as(u2, @intFromBool(lib_as_needed)) << 1) | @intFromBool(as_needed)) {
2016 0b00, 0b11 => {},
2017 0b01 => {
2018 argv.appendAssumeCapacity("--no-as-needed");
2019 as_needed = false;
2020 },
2021 0b10 => {
2022 argv.appendAssumeCapacity("--as-needed");
2023 as_needed = true;
2024 },
2025 }
2026
2027 // By this time, we depend on these libs being dynamically linked
2028 // libraries and not static libraries (the check for that needs to be earlier),
2029 // but they could be full paths to .so files, in which case we
2030 // want to avoid prepending "-l".
2031 argv.appendAssumeCapacity(try dso.path.toString(arena));
2032 },
2033 };
2034
2035 if (!as_needed) {
2036 argv.appendAssumeCapacity("--as-needed");
2037 as_needed = true;
2038 }
2039
2040 // libc++ dep
2041 if (comp.config.link_libcpp) {
2042 try argv.append(try comp.libcxxabi_static_lib.?.full_object_path.toString(arena));
2043 try argv.append(try comp.libcxx_static_lib.?.full_object_path.toString(arena));
2044 }
2045
2046 // libunwind dep
2047 if (comp.config.link_libunwind) {
2048 try argv.append(try comp.libunwind_static_lib.?.full_object_path.toString(arena));
2049 }
2050
2051 // libc dep
2052 diags.flags.missing_libc = false;
2053 if (comp.config.link_libc) {
2054 if (comp.libc_installation != null) {
2055 const needs_grouping = link_mode == .static;
2056 if (needs_grouping) try argv.append("--start-group");
2057 try argv.appendSlice(target_util.libcFullLinkFlags(target));
2058 if (needs_grouping) try argv.append("--end-group");
2059 } else if (target.isGnuLibC()) {
2060 for (glibc.libs) |lib| {
2061 if (lib.removed_in) |rem_in| {
2062 if (target.os.versionRange().gnuLibCVersion().?.order(rem_in) != .lt) continue;
2063 }
2064
2065 const lib_path = try std.fmt.allocPrint(arena, "{}{c}lib{s}.so.{d}", .{
2066 comp.glibc_so_files.?.dir_path, fs.path.sep, lib.name, lib.sover,
2067 });
2068 try argv.append(lib_path);
2069 }
2070 try argv.append(try comp.crtFileAsString(arena, "libc_nonshared.a"));
2071 } else if (target.isMuslLibC()) {
2072 try argv.append(try comp.crtFileAsString(arena, switch (link_mode) {
2073 .static => "libc.a",
2074 .dynamic => "libc.so",
2075 }));
2076 } else if (target.isFreeBSDLibC()) {
2077 for (freebsd.libs) |lib| {
2078 const lib_path = try std.fmt.allocPrint(arena, "{}{c}lib{s}.so.{d}", .{
2079 comp.freebsd_so_files.?.dir_path, fs.path.sep, lib.name, lib.sover,
2080 });
2081 try argv.append(lib_path);
2082 }
2083 } else if (target.isNetBSDLibC()) {
2084 for (netbsd.libs) |lib| {
2085 const lib_path = try std.fmt.allocPrint(arena, "{}{c}lib{s}.so.{d}", .{
2086 comp.netbsd_so_files.?.dir_path, fs.path.sep, lib.name, lib.sover,
2087 });
2088 try argv.append(lib_path);
2089 }
2090 } else {
2091 diags.flags.missing_libc = true;
2092 }
2093
2094 if (comp.zigc_static_lib) |zigc| {
2095 try argv.append(try zigc.full_object_path.toString(arena));
2096 }
2097 }
2098 }
2099
2100 // compiler-rt. Since compiler_rt exports symbols like `memset`, it needs
2101 // to be after the shared libraries, so they are picked up from the shared
2102 // libraries, not libcompiler_rt.
2103 if (compiler_rt_path) |p| {
2104 try argv.append(try p.toString(arena));
2105 }
2106
2107 // crt postlude
2108 if (csu.crtend) |p| try argv.append(try p.toString(arena));
2109 if (csu.crtn) |p| try argv.append(try p.toString(arena));
2110
2111 if (self.base.allow_shlib_undefined) {
2112 try argv.append("--allow-shlib-undefined");
2113 }
2114
2115 switch (self.compress_debug_sections) {
2116 .none => {},
2117 .zlib => try argv.append("--compress-debug-sections=zlib"),
2118 .zstd => try argv.append("--compress-debug-sections=zstd"),
2119 }
2120
2121 if (self.bind_global_refs_locally) {
2122 try argv.append("-Bsymbolic");
2123 }
2124
2125 try link.spawnLld(comp, arena, argv.items);
2126 }
2127
2128 if (!self.base.disable_lld_caching) {
2129 // Update the file with the digest. If it fails we can continue; it only
2130 // means that the next invocation will have an unnecessary cache miss.
2131 std.Build.Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
2132 log.warn("failed to save linking hash digest file: {s}", .{@errorName(err)});
2133 };
2134 // Again failure here only means an unnecessary cache miss.
2135 man.writeManifest() catch |err| {
2136 log.warn("failed to write cache manifest when linking: {s}", .{@errorName(err)});
2137 };
2138 // We hang on to this lock so that the output file path can be used without
2139 // other processes clobbering it.
2140 self.base.lock = man.toOwnedLock();
2141 }
2142}
2143
2144pub fn writeShdrTable(self: *Elf) !void {1434pub fn writeShdrTable(self: *Elf) !void {
2145 const gpa = self.base.comp.gpa;1435 const gpa = self.base.comp.gpa;
2146 const target_endian = self.getTarget().cpu.arch.endian();1436 const target_endian = self.getTarget().cpu.arch.endian();
...@@ -2385,7 +1675,6 @@ pub fn writeElfHeader(self: *Elf) !void {...@@ -2385,7 +1675,6 @@ pub fn writeElfHeader(self: *Elf) !void {
2385}1675}
23861676
2387pub fn freeNav(self: *Elf, nav: InternPool.Nav.Index) void {1677pub fn freeNav(self: *Elf, nav: InternPool.Nav.Index) void {
2388 if (self.llvm_object) |llvm_object| return llvm_object.freeNav(nav);
2389 return self.zigObjectPtr().?.freeNav(self, nav);1678 return self.zigObjectPtr().?.freeNav(self, nav);
2390}1679}
23911680
...@@ -2393,14 +1682,12 @@ pub fn updateFunc(...@@ -2393,14 +1682,12 @@ pub fn updateFunc(
2393 self: *Elf,1682 self: *Elf,
2394 pt: Zcu.PerThread,1683 pt: Zcu.PerThread,
2395 func_index: InternPool.Index,1684 func_index: InternPool.Index,
2396 air: Air,1685 mir: *const codegen.AnyMir,
2397 liveness: Air.Liveness,
2398) link.File.UpdateNavError!void {1686) link.File.UpdateNavError!void {
2399 if (build_options.skip_non_native and builtin.object_format != .elf) {1687 if (build_options.skip_non_native and builtin.object_format != .elf) {
2400 @panic("Attempted to compile for object format that was disabled by build configuration");1688 @panic("Attempted to compile for object format that was disabled by build configuration");
2401 }1689 }
2402 if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(pt, func_index, air, liveness);1690 return self.zigObjectPtr().?.updateFunc(self, pt, func_index, mir);
2403 return self.zigObjectPtr().?.updateFunc(self, pt, func_index, air, liveness);
2404}1691}
24051692
2406pub fn updateNav(1693pub fn updateNav(
...@@ -2411,7 +1698,6 @@ pub fn updateNav(...@@ -2411,7 +1698,6 @@ pub fn updateNav(
2411 if (build_options.skip_non_native and builtin.object_format != .elf) {1698 if (build_options.skip_non_native and builtin.object_format != .elf) {
2412 @panic("Attempted to compile for object format that was disabled by build configuration");1699 @panic("Attempted to compile for object format that was disabled by build configuration");
2413 }1700 }
2414 if (self.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav);
2415 return self.zigObjectPtr().?.updateNav(self, pt, nav);1701 return self.zigObjectPtr().?.updateNav(self, pt, nav);
2416}1702}
24171703
...@@ -2423,7 +1709,6 @@ pub fn updateContainerType(...@@ -2423,7 +1709,6 @@ pub fn updateContainerType(
2423 if (build_options.skip_non_native and builtin.object_format != .elf) {1709 if (build_options.skip_non_native and builtin.object_format != .elf) {
2424 @panic("Attempted to compile for object format that was disabled by build configuration");1710 @panic("Attempted to compile for object format that was disabled by build configuration");
2425 }1711 }
2426 if (self.llvm_object) |_| return;
2427 const zcu = pt.zcu;1712 const zcu = pt.zcu;
2428 const gpa = zcu.gpa;1713 const gpa = zcu.gpa;
2429 return self.zigObjectPtr().?.updateContainerType(pt, ty) catch |err| switch (err) {1714 return self.zigObjectPtr().?.updateContainerType(pt, ty) catch |err| switch (err) {
...@@ -2449,12 +1734,10 @@ pub fn updateExports(...@@ -2449,12 +1734,10 @@ pub fn updateExports(
2449 if (build_options.skip_non_native and builtin.object_format != .elf) {1734 if (build_options.skip_non_native and builtin.object_format != .elf) {
2450 @panic("Attempted to compile for object format that was disabled by build configuration");1735 @panic("Attempted to compile for object format that was disabled by build configuration");
2451 }1736 }
2452 if (self.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices);
2453 return self.zigObjectPtr().?.updateExports(self, pt, exported, export_indices);1737 return self.zigObjectPtr().?.updateExports(self, pt, exported, export_indices);
2454}1738}
24551739
2456pub fn updateLineNumber(self: *Elf, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {1740pub fn updateLineNumber(self: *Elf, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
2457 if (self.llvm_object) |_| return;
2458 return self.zigObjectPtr().?.updateLineNumber(pt, ti_id);1741 return self.zigObjectPtr().?.updateLineNumber(pt, ti_id);
2459}1742}
24601743
...@@ -2463,7 +1746,6 @@ pub fn deleteExport(...@@ -2463,7 +1746,6 @@ pub fn deleteExport(
2463 exported: Zcu.Exported,1746 exported: Zcu.Exported,
2464 name: InternPool.NullTerminatedString,1747 name: InternPool.NullTerminatedString,
2465) void {1748) void {
2466 if (self.llvm_object) |_| return;
2467 return self.zigObjectPtr().?.deleteExport(self, exported, name);1749 return self.zigObjectPtr().?.deleteExport(self, exported, name);
2468}1750}
24691751
...@@ -4140,85 +3422,6 @@ fn shdrTo32(shdr: elf.Elf64_Shdr) elf.Elf32_Shdr {...@@ -4140,85 +3422,6 @@ fn shdrTo32(shdr: elf.Elf64_Shdr) elf.Elf32_Shdr {
4140 };3422 };
4141}3423}
41423424
4143fn getLDMOption(target: std.Target) ?[]const u8 {
4144 // This should only return emulations understood by LLD's parseEmulation().
4145 return switch (target.cpu.arch) {
4146 .aarch64 => switch (target.os.tag) {
4147 .linux => "aarch64linux",
4148 else => "aarch64elf",
4149 },
4150 .aarch64_be => switch (target.os.tag) {
4151 .linux => "aarch64linuxb",
4152 else => "aarch64elfb",
4153 },
4154 .amdgcn => "elf64_amdgpu",
4155 .arm, .thumb => switch (target.os.tag) {
4156 .linux => "armelf_linux_eabi",
4157 else => "armelf",
4158 },
4159 .armeb, .thumbeb => switch (target.os.tag) {
4160 .linux => "armelfb_linux_eabi",
4161 else => "armelfb",
4162 },
4163 .hexagon => "hexagonelf",
4164 .loongarch32 => "elf32loongarch",
4165 .loongarch64 => "elf64loongarch",
4166 .mips => switch (target.os.tag) {
4167 .freebsd => "elf32btsmip_fbsd",
4168 else => "elf32btsmip",
4169 },
4170 .mipsel => switch (target.os.tag) {
4171 .freebsd => "elf32ltsmip_fbsd",
4172 else => "elf32ltsmip",
4173 },
4174 .mips64 => switch (target.os.tag) {
4175 .freebsd => switch (target.abi) {
4176 .gnuabin32, .muslabin32 => "elf32btsmipn32_fbsd",
4177 else => "elf64btsmip_fbsd",
4178 },
4179 else => switch (target.abi) {
4180 .gnuabin32, .muslabin32 => "elf32btsmipn32",
4181 else => "elf64btsmip",
4182 },
4183 },
4184 .mips64el => switch (target.os.tag) {
4185 .freebsd => switch (target.abi) {
4186 .gnuabin32, .muslabin32 => "elf32ltsmipn32_fbsd",
4187 else => "elf64ltsmip_fbsd",
4188 },
4189 else => switch (target.abi) {
4190 .gnuabin32, .muslabin32 => "elf32ltsmipn32",
4191 else => "elf64ltsmip",
4192 },
4193 },
4194 .msp430 => "msp430elf",
4195 .powerpc => switch (target.os.tag) {
4196 .freebsd => "elf32ppc_fbsd",
4197 .linux => "elf32ppclinux",
4198 else => "elf32ppc",
4199 },
4200 .powerpcle => switch (target.os.tag) {
4201 .linux => "elf32lppclinux",
4202 else => "elf32lppc",
4203 },
4204 .powerpc64 => "elf64ppc",
4205 .powerpc64le => "elf64lppc",
4206 .riscv32 => "elf32lriscv",
4207 .riscv64 => "elf64lriscv",
4208 .s390x => "elf64_s390",
4209 .sparc64 => "elf64_sparc",
4210 .x86 => switch (target.os.tag) {
4211 .freebsd => "elf_i386_fbsd",
4212 else => "elf_i386",
4213 },
4214 .x86_64 => switch (target.abi) {
4215 .gnux32, .muslx32 => "elf32_x86_64",
4216 else => "elf_x86_64",
4217 },
4218 else => null,
4219 };
4220}
4221
4222pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {3425pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
4223 return actual_size +| (actual_size / ideal_factor);3426 return actual_size +| (actual_size / ideal_factor);
4224}3427}
...@@ -5303,10 +4506,7 @@ const codegen = @import("../codegen.zig");...@@ -5303,10 +4506,7 @@ const codegen = @import("../codegen.zig");
5303const dev = @import("../dev.zig");4506const dev = @import("../dev.zig");
5304const eh_frame = @import("Elf/eh_frame.zig");4507const eh_frame = @import("Elf/eh_frame.zig");
5305const gc = @import("Elf/gc.zig");4508const gc = @import("Elf/gc.zig");
5306const glibc = @import("../libs/glibc.zig");
5307const musl = @import("../libs/musl.zig");4509const musl = @import("../libs/musl.zig");
5308const freebsd = @import("../libs/freebsd.zig");
5309const netbsd = @import("../libs/netbsd.zig");
5310const link = @import("../link.zig");4510const link = @import("../link.zig");
5311const relocatable = @import("Elf/relocatable.zig");4511const relocatable = @import("Elf/relocatable.zig");
5312const relocation = @import("Elf/relocation.zig");4512const relocation = @import("Elf/relocation.zig");
...@@ -5315,7 +4515,6 @@ const trace = @import("../tracy.zig").trace;...@@ -5315,7 +4515,6 @@ const trace = @import("../tracy.zig").trace;
5315const synthetic_sections = @import("Elf/synthetic_sections.zig");4515const synthetic_sections = @import("Elf/synthetic_sections.zig");
53164516
5317const Merge = @import("Elf/Merge.zig");4517const Merge = @import("Elf/Merge.zig");
5318const Air = @import("../Air.zig");
5319const Archive = @import("Elf/Archive.zig");4518const Archive = @import("Elf/Archive.zig");
5320const AtomList = @import("Elf/AtomList.zig");4519const AtomList = @import("Elf/AtomList.zig");
5321const Compilation = @import("../Compilation.zig");4520const Compilation = @import("../Compilation.zig");
...@@ -5332,7 +4531,6 @@ const GotSection = synthetic_sections.GotSection;...@@ -5332,7 +4531,6 @@ const GotSection = synthetic_sections.GotSection;
5332const GotPltSection = synthetic_sections.GotPltSection;4531const GotPltSection = synthetic_sections.GotPltSection;
5333const HashSection = synthetic_sections.HashSection;4532const HashSection = synthetic_sections.HashSection;
5334const LinkerDefined = @import("Elf/LinkerDefined.zig");4533const LinkerDefined = @import("Elf/LinkerDefined.zig");
5335const LlvmObject = @import("../codegen/llvm.zig").Object;
5336const Zcu = @import("../Zcu.zig");4534const Zcu = @import("../Zcu.zig");
5337const Object = @import("Elf/Object.zig");4535const Object = @import("Elf/Object.zig");
5338const InternPool = @import("../InternPool.zig");4536const InternPool = @import("../InternPool.zig");
src/link/Elf/Symbol.zig-3
...@@ -462,9 +462,6 @@ pub const Flags = packed struct {...@@ -462,9 +462,6 @@ pub const Flags = packed struct {
462462
463 /// Whether the symbol is a TLS variable.463 /// Whether the symbol is a TLS variable.
464 is_tls: bool = false,464 is_tls: bool = false,
465
466 /// Whether the symbol is an extern pointer (as opposed to function).
467 is_extern_ptr: bool = false,
468};465};
469466
470pub const Extra = struct {467pub const Extra = struct {
src/link/Elf/ZigObject.zig+9-17
...@@ -310,7 +310,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {...@@ -310,7 +310,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
310 if (self.dwarf) |*dwarf| {310 if (self.dwarf) |*dwarf| {
311 const pt: Zcu.PerThread = .activate(elf_file.base.comp.zcu.?, tid);311 const pt: Zcu.PerThread = .activate(elf_file.base.comp.zcu.?, tid);
312 defer pt.deactivate();312 defer pt.deactivate();
313 try dwarf.flushModule(pt);313 try dwarf.flush(pt);
314314
315 const gpa = elf_file.base.comp.gpa;315 const gpa = elf_file.base.comp.gpa;
316 const cpu_arch = elf_file.getTarget().cpu.arch;316 const cpu_arch = elf_file.getTarget().cpu.arch;
...@@ -481,7 +481,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {...@@ -481,7 +481,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
481 self.debug_str_section_dirty = false;481 self.debug_str_section_dirty = false;
482 }482 }
483483
484 // The point of flushModule() is to commit changes, so in theory, nothing should484 // The point of flush() is to commit changes, so in theory, nothing should
485 // be dirty after this. However, it is possible for some things to remain485 // be dirty after this. However, it is possible for some things to remain
486 // dirty because they fail to be written in the event of compile errors,486 // dirty because they fail to be written in the event of compile errors,
487 // such as debug_line_header_dirty and debug_info_header_dirty.487 // such as debug_line_header_dirty and debug_info_header_dirty.
...@@ -661,7 +661,7 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void {...@@ -661,7 +661,7 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void {
661 if (shdr.sh_type == elf.SHT_NOBITS) continue;661 if (shdr.sh_type == elf.SHT_NOBITS) continue;
662 if (atom_ptr.scanRelocsRequiresCode(elf_file)) {662 if (atom_ptr.scanRelocsRequiresCode(elf_file)) {
663 // TODO ideally we don't have to fetch the code here.663 // TODO ideally we don't have to fetch the code here.
664 // Perhaps it would make sense to save the code until flushModule where we664 // Perhaps it would make sense to save the code until flush where we
665 // would free all of generated code?665 // would free all of generated code?
666 const code = try self.codeAlloc(elf_file, atom_index);666 const code = try self.codeAlloc(elf_file, atom_index);
667 defer gpa.free(code);667 defer gpa.free(code);
...@@ -1075,7 +1075,7 @@ pub fn getOrCreateMetadataForLazySymbol(...@@ -1075,7 +1075,7 @@ pub fn getOrCreateMetadataForLazySymbol(
1075 }1075 }
1076 state_ptr.* = .pending_flush;1076 state_ptr.* = .pending_flush;
1077 const symbol_index = symbol_index_ptr.*;1077 const symbol_index = symbol_index_ptr.*;
1078 // anyerror needs to be deferred until flushModule1078 // anyerror needs to be deferred until flush
1079 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbol(elf_file, pt, lazy_sym, symbol_index);1079 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbol(elf_file, pt, lazy_sym, symbol_index);
1080 return symbol_index;1080 return symbol_index;
1081}1081}
...@@ -1142,7 +1142,6 @@ fn getNavShdrIndex(...@@ -1142,7 +1142,6 @@ fn getNavShdrIndex(
1142 const gpa = elf_file.base.comp.gpa;1142 const gpa = elf_file.base.comp.gpa;
1143 const ptr_size = elf_file.ptrWidthBytes();1143 const ptr_size = elf_file.ptrWidthBytes();
1144 const ip = &zcu.intern_pool;1144 const ip = &zcu.intern_pool;
1145 const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
1146 const nav_val = zcu.navValue(nav_index);1145 const nav_val = zcu.navValue(nav_index);
1147 if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) {1146 if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) {
1148 if (self.text_index) |symbol_index|1147 if (self.text_index) |symbol_index|
...@@ -1162,7 +1161,7 @@ fn getNavShdrIndex(...@@ -1162,7 +1161,7 @@ fn getNavShdrIndex(
1162 else => .{ true, false, nav_val.toIntern() },1161 else => .{ true, false, nav_val.toIntern() },
1163 };1162 };
1164 const has_relocs = self.symbol(sym_index).atom(elf_file).?.relocs(elf_file).len > 0;1163 const has_relocs = self.symbol(sym_index).atom(elf_file).?.relocs(elf_file).len > 0;
1165 if (any_non_single_threaded and is_threadlocal) {1164 if (is_threadlocal and elf_file.base.comp.config.any_non_single_threaded) {
1166 const is_bss = !has_relocs and for (code) |byte| {1165 const is_bss = !has_relocs and for (code) |byte| {
1167 if (byte != 0) break false;1166 if (byte != 0) break false;
1168 } else true;1167 } else true;
...@@ -1416,8 +1415,7 @@ pub fn updateFunc(...@@ -1416,8 +1415,7 @@ pub fn updateFunc(
1416 elf_file: *Elf,1415 elf_file: *Elf,
1417 pt: Zcu.PerThread,1416 pt: Zcu.PerThread,
1418 func_index: InternPool.Index,1417 func_index: InternPool.Index,
1419 air: Air,1418 mir: *const codegen.AnyMir,
1420 liveness: Air.Liveness,
1421) link.File.UpdateNavError!void {1419) link.File.UpdateNavError!void {
1422 const tracy = trace(@src());1420 const tracy = trace(@src());
1423 defer tracy.end();1421 defer tracy.end();
...@@ -1438,13 +1436,12 @@ pub fn updateFunc(...@@ -1438,13 +1436,12 @@ pub fn updateFunc(
1438 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;1436 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
1439 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();1437 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
14401438
1441 try codegen.generateFunction(1439 try codegen.emitFunction(
1442 &elf_file.base,1440 &elf_file.base,
1443 pt,1441 pt,
1444 zcu.navSrcLoc(func.owner_nav),1442 zcu.navSrcLoc(func.owner_nav),
1445 func_index,1443 func_index,
1446 air,1444 mir,
1447 liveness,
1448 &code_buffer,1445 &code_buffer,
1449 if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none,1446 if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none,
1450 );1447 );
...@@ -1544,11 +1541,7 @@ pub fn updateNav(...@@ -1544,11 +1541,7 @@ pub fn updateNav(
1544 nav.name.toSlice(ip),1541 nav.name.toSlice(ip),
1545 @"extern".lib_name.toSlice(ip),1542 @"extern".lib_name.toSlice(ip),
1546 );1543 );
1547 if (!ip.isFunctionType(@"extern".ty)) {1544 if (@"extern".is_threadlocal and elf_file.base.comp.config.any_non_single_threaded) self.symbol(sym_index).flags.is_tls = true;
1548 const sym = self.symbol(sym_index);
1549 sym.flags.is_extern_ptr = true;
1550 if (@"extern".is_threadlocal) sym.flags.is_tls = true;
1551 }
1552 if (self.dwarf) |*dwarf| dwarf: {1545 if (self.dwarf) |*dwarf| dwarf: {
1553 var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf;1546 var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf;
1554 defer debug_wip_nav.deinit();1547 defer debug_wip_nav.deinit();
...@@ -2361,7 +2354,6 @@ const trace = @import("../../tracy.zig").trace;...@@ -2361,7 +2354,6 @@ const trace = @import("../../tracy.zig").trace;
2361const std = @import("std");2354const std = @import("std");
2362const Allocator = std.mem.Allocator;2355const Allocator = std.mem.Allocator;
23632356
2364const Air = @import("../../Air.zig");
2365const Archive = @import("Archive.zig");2357const Archive = @import("Archive.zig");
2366const Atom = @import("Atom.zig");2358const Atom = @import("Atom.zig");
2367const Dwarf = @import("../Dwarf.zig");2359const Dwarf = @import("../Dwarf.zig");
src/link/Goff.zig+21-28
...@@ -13,14 +13,12 @@ const Path = std.Build.Cache.Path;...@@ -13,14 +13,12 @@ const Path = std.Build.Cache.Path;
13const Zcu = @import("../Zcu.zig");13const Zcu = @import("../Zcu.zig");
14const InternPool = @import("../InternPool.zig");14const InternPool = @import("../InternPool.zig");
15const Compilation = @import("../Compilation.zig");15const Compilation = @import("../Compilation.zig");
16const codegen = @import("../codegen.zig");
16const link = @import("../link.zig");17const link = @import("../link.zig");
17const trace = @import("../tracy.zig").trace;18const trace = @import("../tracy.zig").trace;
18const build_options = @import("build_options");19const build_options = @import("build_options");
19const Air = @import("../Air.zig");
20const LlvmObject = @import("../codegen/llvm.zig").Object;
2120
22base: link.File,21base: link.File,
23llvm_object: LlvmObject.Ptr,
2422
25pub fn createEmpty(23pub fn createEmpty(
26 arena: Allocator,24 arena: Allocator,
...@@ -36,23 +34,20 @@ pub fn createEmpty(...@@ -36,23 +34,20 @@ pub fn createEmpty(
36 assert(!use_lld); // Caught by Compilation.Config.resolve.34 assert(!use_lld); // Caught by Compilation.Config.resolve.
37 assert(target.os.tag == .zos); // Caught by Compilation.Config.resolve.35 assert(target.os.tag == .zos); // Caught by Compilation.Config.resolve.
3836
39 const llvm_object = try LlvmObject.create(arena, comp);
40 const goff = try arena.create(Goff);37 const goff = try arena.create(Goff);
41 goff.* = .{38 goff.* = .{
42 .base = .{39 .base = .{
43 .tag = .goff,40 .tag = .goff,
44 .comp = comp,41 .comp = comp,
45 .emit = emit,42 .emit = emit,
46 .zcu_object_sub_path = emit.sub_path,43 .zcu_object_basename = emit.sub_path,
47 .gc_sections = options.gc_sections orelse false,44 .gc_sections = options.gc_sections orelse false,
48 .print_gc_sections = options.print_gc_sections,45 .print_gc_sections = options.print_gc_sections,
49 .stack_size = options.stack_size orelse 0,46 .stack_size = options.stack_size orelse 0,
50 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,47 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
51 .file = null,48 .file = null,
52 .disable_lld_caching = options.disable_lld_caching,
53 .build_id = options.build_id,49 .build_id = options.build_id,
54 },50 },
55 .llvm_object = llvm_object,
56 };51 };
5752
58 return goff;53 return goff;
...@@ -70,27 +65,27 @@ pub fn open(...@@ -70,27 +65,27 @@ pub fn open(
70}65}
7166
72pub fn deinit(self: *Goff) void {67pub fn deinit(self: *Goff) void {
73 self.llvm_object.deinit();68 _ = self;
74}69}
7570
76pub fn updateFunc(71pub fn updateFunc(
77 self: *Goff,72 self: *Goff,
78 pt: Zcu.PerThread,73 pt: Zcu.PerThread,
79 func_index: InternPool.Index,74 func_index: InternPool.Index,
80 air: Air,75 mir: *const codegen.AnyMir,
81 liveness: Air.Liveness,
82) link.File.UpdateNavError!void {76) link.File.UpdateNavError!void {
83 if (build_options.skip_non_native and builtin.object_format != .goff)77 _ = self;
84 @panic("Attempted to compile for object format that was disabled by build configuration");78 _ = pt;
8579 _ = func_index;
86 try self.llvm_object.updateFunc(pt, func_index, air, liveness);80 _ = mir;
81 unreachable; // we always use llvm
87}82}
8883
89pub fn updateNav(self: *Goff, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {84pub fn updateNav(self: *Goff, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {
90 if (build_options.skip_non_native and builtin.object_format != .goff)85 _ = self;
91 @panic("Attempted to compile for object format that was disabled by build configuration");86 _ = pt;
9287 _ = nav;
93 return self.llvm_object.updateNav(pt, nav);88 unreachable; // we always use llvm
94}89}
9590
96pub fn updateExports(91pub fn updateExports(
...@@ -99,21 +94,19 @@ pub fn updateExports(...@@ -99,21 +94,19 @@ pub fn updateExports(
99 exported: Zcu.Exported,94 exported: Zcu.Exported,
100 export_indices: []const Zcu.Export.Index,95 export_indices: []const Zcu.Export.Index,
101) !void {96) !void {
102 if (build_options.skip_non_native and builtin.object_format != .goff)97 _ = self;
103 @panic("Attempted to compile for object format that was disabled by build configuration");98 _ = pt;
10499 _ = exported;
105 return self.llvm_object.updateExports(pt, exported, export_indices);100 _ = export_indices;
101 unreachable; // we always use llvm
106}102}
107103
108pub fn flush(self: *Goff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {104pub fn flush(self: *Goff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
109 return self.flushModule(arena, tid, prog_node);
110}
111
112pub fn flushModule(self: *Goff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
113 if (build_options.skip_non_native and builtin.object_format != .goff)105 if (build_options.skip_non_native and builtin.object_format != .goff)
114 @panic("Attempted to compile for object format that was disabled by build configuration");106 @panic("Attempted to compile for object format that was disabled by build configuration");
115107
108 _ = self;
109 _ = arena;
116 _ = tid;110 _ = tid;
117111 _ = prog_node;
118 try self.base.emitLlvmObject(arena, self.llvm_object, prog_node);
119}112}
src/link/Lld.zig created+1757
...@@ -0,0 +1,1757 @@
1base: link.File,
2ofmt: union(enum) {
3 elf: Elf,
4 coff: Coff,
5 wasm: Wasm,
6},
7
8const Coff = struct {
9 image_base: u64,
10 entry: link.File.OpenOptions.Entry,
11 pdb_out_path: ?[]const u8,
12 repro: bool,
13 tsaware: bool,
14 nxcompat: bool,
15 dynamicbase: bool,
16 /// TODO this and minor_subsystem_version should be combined into one property and left as
17 /// default or populated together. They should not be separate fields.
18 major_subsystem_version: u16,
19 minor_subsystem_version: u16,
20 lib_directories: []const Cache.Directory,
21 module_definition_file: ?[]const u8,
22 subsystem: ?std.Target.SubSystem,
23 /// These flags are populated by `codegen.llvm.updateExports` to allow us to guess the subsystem.
24 lld_export_flags: struct {
25 c_main: bool,
26 winmain: bool,
27 wwinmain: bool,
28 winmain_crt_startup: bool,
29 wwinmain_crt_startup: bool,
30 dllmain_crt_startup: bool,
31 },
32 fn init(comp: *Compilation, options: link.File.OpenOptions) !Coff {
33 const target = comp.root_mod.resolved_target.result;
34 const output_mode = comp.config.output_mode;
35 return .{
36 .image_base = options.image_base orelse switch (output_mode) {
37 .Exe => switch (target.cpu.arch) {
38 .aarch64, .x86_64 => 0x140000000,
39 .thumb, .x86 => 0x400000,
40 else => unreachable,
41 },
42 .Lib => switch (target.cpu.arch) {
43 .aarch64, .x86_64 => 0x180000000,
44 .thumb, .x86 => 0x10000000,
45 else => unreachable,
46 },
47 .Obj => 0,
48 },
49 .entry = options.entry,
50 .pdb_out_path = options.pdb_out_path,
51 .repro = options.repro,
52 .tsaware = options.tsaware,
53 .nxcompat = options.nxcompat,
54 .dynamicbase = options.dynamicbase,
55 .major_subsystem_version = options.major_subsystem_version orelse 6,
56 .minor_subsystem_version = options.minor_subsystem_version orelse 0,
57 .lib_directories = options.lib_directories,
58 .module_definition_file = options.module_definition_file,
59 // Subsystem depends on the set of public symbol names from linked objects.
60 // See LinkerDriver::inferSubsystem from the LLD project for the flow chart.
61 .subsystem = options.subsystem,
62 // These flags are initially all `false`; the LLVM backend populates them when it learns about exports.
63 .lld_export_flags = .{
64 .c_main = false,
65 .winmain = false,
66 .wwinmain = false,
67 .winmain_crt_startup = false,
68 .wwinmain_crt_startup = false,
69 .dllmain_crt_startup = false,
70 },
71 };
72 }
73};
74pub const Elf = struct {
75 entry_name: ?[]const u8,
76 hash_style: HashStyle,
77 image_base: u64,
78 linker_script: ?[]const u8,
79 version_script: ?[]const u8,
80 sort_section: ?SortSection,
81 print_icf_sections: bool,
82 print_map: bool,
83 emit_relocs: bool,
84 z_nodelete: bool,
85 z_notext: bool,
86 z_defs: bool,
87 z_origin: bool,
88 z_nocopyreloc: bool,
89 z_now: bool,
90 z_relro: bool,
91 z_common_page_size: ?u64,
92 z_max_page_size: ?u64,
93 rpath_list: []const []const u8,
94 symbol_wrap_set: []const []const u8,
95 soname: ?[]const u8,
96 allow_undefined_version: bool,
97 enable_new_dtags: ?bool,
98 compress_debug_sections: CompressDebugSections,
99 bind_global_refs_locally: bool,
100 pub const HashStyle = enum { sysv, gnu, both };
101 pub const SortSection = enum { name, alignment };
102 pub const CompressDebugSections = enum { none, zlib, zstd };
103
104 fn init(comp: *Compilation, options: link.File.OpenOptions) !Elf {
105 const PtrWidth = enum { p32, p64 };
106 const target = comp.root_mod.resolved_target.result;
107 const output_mode = comp.config.output_mode;
108 const is_dyn_lib = output_mode == .Lib and comp.config.link_mode == .dynamic;
109 const ptr_width: PtrWidth = switch (target.ptrBitWidth()) {
110 0...32 => .p32,
111 33...64 => .p64,
112 else => return error.UnsupportedElfArchitecture,
113 };
114 const default_entry_name: []const u8 = switch (target.cpu.arch) {
115 .mips, .mipsel, .mips64, .mips64el => "__start",
116 else => "_start",
117 };
118 return .{
119 .entry_name = switch (options.entry) {
120 .disabled => null,
121 .default => if (output_mode != .Exe) null else default_entry_name,
122 .enabled => default_entry_name,
123 .named => |name| name,
124 },
125 .hash_style = options.hash_style,
126 .image_base = b: {
127 if (is_dyn_lib) break :b 0;
128 if (output_mode == .Exe and comp.config.pie) break :b 0;
129 break :b options.image_base orelse switch (ptr_width) {
130 .p32 => 0x10000,
131 .p64 => 0x1000000,
132 };
133 },
134 .linker_script = options.linker_script,
135 .version_script = options.version_script,
136 .sort_section = options.sort_section,
137 .print_icf_sections = options.print_icf_sections,
138 .print_map = options.print_map,
139 .emit_relocs = options.emit_relocs,
140 .z_nodelete = options.z_nodelete,
141 .z_notext = options.z_notext,
142 .z_defs = options.z_defs,
143 .z_origin = options.z_origin,
144 .z_nocopyreloc = options.z_nocopyreloc,
145 .z_now = options.z_now,
146 .z_relro = options.z_relro,
147 .z_common_page_size = options.z_common_page_size,
148 .z_max_page_size = options.z_max_page_size,
149 .rpath_list = options.rpath_list,
150 .symbol_wrap_set = options.symbol_wrap_set.keys(),
151 .soname = options.soname,
152 .allow_undefined_version = options.allow_undefined_version,
153 .enable_new_dtags = options.enable_new_dtags,
154 .compress_debug_sections = options.compress_debug_sections,
155 .bind_global_refs_locally = options.bind_global_refs_locally,
156 };
157 }
158};
159const Wasm = struct {
160 /// Symbol name of the entry function to export
161 entry_name: ?[]const u8,
162 /// When true, will import the function table from the host environment.
163 import_table: bool,
164 /// When true, will export the function table to the host environment.
165 export_table: bool,
166 /// When defined, sets the initial memory size of the memory.
167 initial_memory: ?u64,
168 /// When defined, sets the maximum memory size of the memory.
169 max_memory: ?u64,
170 /// When defined, sets the start of the data section.
171 global_base: ?u64,
172 /// Set of *global* symbol names to export to the host environment.
173 export_symbol_names: []const []const u8,
174 /// When true, will allow undefined symbols
175 import_symbols: bool,
176 fn init(comp: *Compilation, options: link.File.OpenOptions) !Wasm {
177 const default_entry_name: []const u8 = switch (comp.config.wasi_exec_model) {
178 .reactor => "_initialize",
179 .command => "_start",
180 };
181 return .{
182 .entry_name = switch (options.entry) {
183 .disabled => null,
184 .default => if (comp.config.output_mode != .Exe) null else default_entry_name,
185 .enabled => default_entry_name,
186 .named => |name| name,
187 },
188 .import_table = options.import_table,
189 .export_table = options.export_table,
190 .initial_memory = options.initial_memory,
191 .max_memory = options.max_memory,
192 .global_base = options.global_base,
193 .export_symbol_names = options.export_symbol_names,
194 .import_symbols = options.import_symbols,
195 };
196 }
197};
198
199pub fn createEmpty(
200 arena: Allocator,
201 comp: *Compilation,
202 emit: Cache.Path,
203 options: link.File.OpenOptions,
204) !*Lld {
205 const target = comp.root_mod.resolved_target.result;
206 const output_mode = comp.config.output_mode;
207 const optimize_mode = comp.root_mod.optimize_mode;
208 const is_native_os = comp.root_mod.resolved_target.is_native_os;
209
210 const obj_file_ext: []const u8 = switch (target.ofmt) {
211 .coff => "obj",
212 .elf, .wasm => "o",
213 else => unreachable,
214 };
215 const gc_sections: bool = options.gc_sections orelse switch (target.ofmt) {
216 .coff => optimize_mode != .Debug,
217 .elf => optimize_mode != .Debug and output_mode != .Obj,
218 .wasm => output_mode != .Obj,
219 else => unreachable,
220 };
221 const stack_size: u64 = options.stack_size orelse default: {
222 if (target.ofmt == .wasm and target.os.tag == .freestanding)
223 break :default 1 * 1024 * 1024; // 1 MiB
224 break :default 16 * 1024 * 1024; // 16 MiB
225 };
226
227 const lld = try arena.create(Lld);
228 lld.* = .{
229 .base = .{
230 .tag = .lld,
231 .comp = comp,
232 .emit = emit,
233 .zcu_object_basename = try allocPrint(arena, "{s}_zcu.{s}", .{ fs.path.stem(emit.sub_path), obj_file_ext }),
234 .gc_sections = gc_sections,
235 .print_gc_sections = options.print_gc_sections,
236 .stack_size = stack_size,
237 .allow_shlib_undefined = options.allow_shlib_undefined orelse !is_native_os,
238 .file = null,
239 .build_id = options.build_id,
240 },
241 .ofmt = switch (target.ofmt) {
242 .coff => .{ .coff = try .init(comp, options) },
243 .elf => .{ .elf = try .init(comp, options) },
244 .wasm => .{ .wasm = try .init(comp, options) },
245 else => unreachable,
246 },
247 };
248 return lld;
249}
250pub fn deinit(lld: *Lld) void {
251 _ = lld;
252}
253pub fn flush(
254 lld: *Lld,
255 arena: Allocator,
256 tid: Zcu.PerThread.Id,
257 prog_node: std.Progress.Node,
258) link.File.FlushError!void {
259 dev.check(.lld_linker);
260 _ = tid;
261
262 const tracy = trace(@src());
263 defer tracy.end();
264
265 const sub_prog_node = prog_node.start("LLD Link", 0);
266 defer sub_prog_node.end();
267
268 const comp = lld.base.comp;
269 const result = if (comp.config.output_mode == .Lib and comp.config.link_mode == .static) r: {
270 if (!@import("build_options").have_llvm or !comp.config.use_lib_llvm) {
271 return lld.base.comp.link_diags.fail("using lld without libllvm not implemented", .{});
272 }
273 break :r linkAsArchive(lld, arena);
274 } else switch (lld.ofmt) {
275 .coff => coffLink(lld, arena),
276 .elf => elfLink(lld, arena),
277 .wasm => wasmLink(lld, arena),
278 };
279 result catch |err| switch (err) {
280 error.OutOfMemory, error.LinkFailure => |e| return e,
281 else => |e| return lld.base.comp.link_diags.fail("failed to link with LLD: {s}", .{@errorName(e)}),
282 };
283}
284
285fn linkAsArchive(lld: *Lld, arena: Allocator) !void {
286 const base = &lld.base;
287 const comp = base.comp;
288 const directory = base.emit.root_dir; // Just an alias to make it shorter to type.
289 const full_out_path = try directory.join(arena, &[_][]const u8{base.emit.sub_path});
290 const full_out_path_z = try arena.dupeZ(u8, full_out_path);
291 const opt_zcu = comp.zcu;
292
293 const zcu_obj_path: ?Cache.Path = if (opt_zcu != null) p: {
294 break :p try comp.resolveEmitPathFlush(arena, .temp, base.zcu_object_basename.?);
295 } else null;
296
297 log.debug("zcu_obj_path={?}", .{zcu_obj_path});
298
299 const compiler_rt_path: ?Cache.Path = if (comp.compiler_rt_strat == .obj)
300 comp.compiler_rt_obj.?.full_object_path
301 else
302 null;
303
304 const ubsan_rt_path: ?Cache.Path = if (comp.ubsan_rt_strat == .obj)
305 comp.ubsan_rt_obj.?.full_object_path
306 else
307 null;
308
309 // This function follows the same pattern as link.Elf.linkWithLLD so if you want some
310 // insight as to what's going on here you can read that function body which is more
311 // well-commented.
312
313 const link_inputs = comp.link_inputs;
314
315 var object_files: std.ArrayListUnmanaged([*:0]const u8) = .empty;
316
317 try object_files.ensureUnusedCapacity(arena, link_inputs.len);
318 for (link_inputs) |input| {
319 object_files.appendAssumeCapacity(try input.path().?.toStringZ(arena));
320 }
321
322 try object_files.ensureUnusedCapacity(arena, comp.c_object_table.count() +
323 comp.win32_resource_table.count() + 2);
324
325 for (comp.c_object_table.keys()) |key| {
326 object_files.appendAssumeCapacity(try key.status.success.object_path.toStringZ(arena));
327 }
328 for (comp.win32_resource_table.keys()) |key| {
329 object_files.appendAssumeCapacity(try arena.dupeZ(u8, key.status.success.res_path));
330 }
331 if (zcu_obj_path) |p| object_files.appendAssumeCapacity(try p.toStringZ(arena));
332 if (compiler_rt_path) |p| object_files.appendAssumeCapacity(try p.toStringZ(arena));
333 if (ubsan_rt_path) |p| object_files.appendAssumeCapacity(try p.toStringZ(arena));
334
335 if (comp.verbose_link) {
336 std.debug.print("ar rcs {s}", .{full_out_path_z});
337 for (object_files.items) |arg| {
338 std.debug.print(" {s}", .{arg});
339 }
340 std.debug.print("\n", .{});
341 }
342
343 const llvm_bindings = @import("../codegen/llvm/bindings.zig");
344 const llvm = @import("../codegen/llvm.zig");
345 const target = comp.root_mod.resolved_target.result;
346 llvm.initializeLLVMTarget(target.cpu.arch);
347 const bad = llvm_bindings.WriteArchive(
348 full_out_path_z,
349 object_files.items.ptr,
350 object_files.items.len,
351 switch (target.os.tag) {
352 .aix => .AIXBIG,
353 .windows => .COFF,
354 else => if (target.os.tag.isDarwin()) .DARWIN else .GNU,
355 },
356 );
357 if (bad) return error.UnableToWriteArchive;
358}
359
360fn coffLink(lld: *Lld, arena: Allocator) !void {
361 const comp = lld.base.comp;
362 const gpa = comp.gpa;
363 const base = &lld.base;
364 const coff = &lld.ofmt.coff;
365
366 const directory = base.emit.root_dir; // Just an alias to make it shorter to type.
367 const full_out_path = try directory.join(arena, &[_][]const u8{base.emit.sub_path});
368
369 const zcu_obj_path: ?Cache.Path = if (comp.zcu != null) p: {
370 break :p try comp.resolveEmitPathFlush(arena, .temp, base.zcu_object_basename.?);
371 } else null;
372
373 const is_lib = comp.config.output_mode == .Lib;
374 const is_dyn_lib = comp.config.link_mode == .dynamic and is_lib;
375 const is_exe_or_dyn_lib = is_dyn_lib or comp.config.output_mode == .Exe;
376 const link_in_crt = comp.config.link_libc and is_exe_or_dyn_lib;
377 const target = comp.root_mod.resolved_target.result;
378 const optimize_mode = comp.root_mod.optimize_mode;
379 const entry_name: ?[]const u8 = switch (coff.entry) {
380 // This logic isn't quite right for disabled or enabled. No point in fixing it
381 // when the goal is to eliminate dependency on LLD anyway.
382 // https://github.com/ziglang/zig/issues/17751
383 .disabled, .default, .enabled => null,
384 .named => |name| name,
385 };
386
387 if (comp.config.output_mode == .Obj) {
388 // LLD's COFF driver does not support the equivalent of `-r` so we do a simple file copy
389 // here. TODO: think carefully about how we can avoid this redundant operation when doing
390 // build-obj. See also the corresponding TODO in linkAsArchive.
391 const the_object_path = blk: {
392 if (link.firstObjectInput(comp.link_inputs)) |obj| break :blk obj.path;
393
394 if (comp.c_object_table.count() != 0)
395 break :blk comp.c_object_table.keys()[0].status.success.object_path;
396
397 if (zcu_obj_path) |p|
398 break :blk p;
399
400 // TODO I think this is unreachable. Audit this situation when solving the above TODO
401 // regarding eliding redundant object -> object transformations.
402 return error.NoObjectsToLink;
403 };
404 try std.fs.Dir.copyFile(
405 the_object_path.root_dir.handle,
406 the_object_path.sub_path,
407 directory.handle,
408 base.emit.sub_path,
409 .{},
410 );
411 } else {
412 // Create an LLD command line and invoke it.
413 var argv = std.ArrayList([]const u8).init(gpa);
414 defer argv.deinit();
415 // We will invoke ourselves as a child process to gain access to LLD.
416 // This is necessary because LLD does not behave properly as a library -
417 // it calls exit() and does not reset all global data between invocations.
418 const linker_command = "lld-link";
419 try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command });
420
421 if (target.isMinGW()) {
422 try argv.append("-lldmingw");
423 }
424
425 try argv.append("-ERRORLIMIT:0");
426 try argv.append("-NOLOGO");
427 if (comp.config.debug_format != .strip) {
428 try argv.append("-DEBUG");
429
430 const out_ext = std.fs.path.extension(full_out_path);
431 const out_pdb = coff.pdb_out_path orelse try allocPrint(arena, "{s}.pdb", .{
432 full_out_path[0 .. full_out_path.len - out_ext.len],
433 });
434 const out_pdb_basename = std.fs.path.basename(out_pdb);
435
436 try argv.append(try allocPrint(arena, "-PDB:{s}", .{out_pdb}));
437 try argv.append(try allocPrint(arena, "-PDBALTPATH:{s}", .{out_pdb_basename}));
438 }
439 if (comp.version) |version| {
440 try argv.append(try allocPrint(arena, "-VERSION:{}.{}", .{ version.major, version.minor }));
441 }
442
443 if (target_util.llvmMachineAbi(target)) |mabi| {
444 try argv.append(try allocPrint(arena, "-MLLVM:-target-abi={s}", .{mabi}));
445 }
446
447 try argv.append(try allocPrint(arena, "-MLLVM:-float-abi={s}", .{if (target.abi.float() == .hard) "hard" else "soft"}));
448
449 if (comp.config.lto != .none) {
450 switch (optimize_mode) {
451 .Debug => {},
452 .ReleaseSmall => try argv.append("-OPT:lldlto=2"),
453 .ReleaseFast, .ReleaseSafe => try argv.append("-OPT:lldlto=3"),
454 }
455 }
456 if (comp.config.output_mode == .Exe) {
457 try argv.append(try allocPrint(arena, "-STACK:{d}", .{base.stack_size}));
458 }
459 try argv.append(try allocPrint(arena, "-BASE:{d}", .{coff.image_base}));
460
461 switch (base.build_id) {
462 .none => try argv.append("-BUILD-ID:NO"),
463 .fast => try argv.append("-BUILD-ID"),
464 .uuid, .sha1, .md5, .hexstring => {},
465 }
466
467 if (target.cpu.arch == .x86) {
468 try argv.append("-MACHINE:X86");
469 } else if (target.cpu.arch == .x86_64) {
470 try argv.append("-MACHINE:X64");
471 } else if (target.cpu.arch == .thumb) {
472 try argv.append("-MACHINE:ARM");
473 } else if (target.cpu.arch == .aarch64) {
474 try argv.append("-MACHINE:ARM64");
475 }
476
477 for (comp.force_undefined_symbols.keys()) |symbol| {
478 try argv.append(try allocPrint(arena, "-INCLUDE:{s}", .{symbol}));
479 }
480
481 if (is_dyn_lib) {
482 try argv.append("-DLL");
483 }
484
485 if (entry_name) |name| {
486 try argv.append(try allocPrint(arena, "-ENTRY:{s}", .{name}));
487 }
488
489 if (coff.repro) {
490 try argv.append("-BREPRO");
491 }
492
493 if (coff.tsaware) {
494 try argv.append("-tsaware");
495 }
496 if (coff.nxcompat) {
497 try argv.append("-nxcompat");
498 }
499 if (!coff.dynamicbase) {
500 try argv.append("-dynamicbase:NO");
501 }
502 if (base.allow_shlib_undefined) {
503 try argv.append("-FORCE:UNRESOLVED");
504 }
505
506 try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path}));
507
508 if (comp.emit_implib) |raw_emit_path| {
509 const path = try comp.resolveEmitPathFlush(arena, .temp, raw_emit_path);
510 try argv.append(try allocPrint(arena, "-IMPLIB:{}", .{path}));
511 }
512
513 if (comp.config.link_libc) {
514 if (comp.libc_installation) |libc_installation| {
515 try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.crt_dir.?}));
516
517 if (target.abi == .msvc or target.abi == .itanium) {
518 try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.msvc_lib_dir.?}));
519 try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.kernel32_lib_dir.?}));
520 }
521 }
522 }
523
524 for (coff.lib_directories) |lib_directory| {
525 try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_directory.path orelse "."}));
526 }
527
528 try argv.ensureUnusedCapacity(comp.link_inputs.len);
529 for (comp.link_inputs) |link_input| switch (link_input) {
530 .dso_exact => unreachable, // not applicable to PE/COFF
531 inline .dso, .res => |x| {
532 argv.appendAssumeCapacity(try x.path.toString(arena));
533 },
534 .object, .archive => |obj| {
535 if (obj.must_link) {
536 argv.appendAssumeCapacity(try allocPrint(arena, "-WHOLEARCHIVE:{}", .{@as(Cache.Path, obj.path)}));
537 } else {
538 argv.appendAssumeCapacity(try obj.path.toString(arena));
539 }
540 },
541 };
542
543 for (comp.c_object_table.keys()) |key| {
544 try argv.append(try key.status.success.object_path.toString(arena));
545 }
546
547 for (comp.win32_resource_table.keys()) |key| {
548 try argv.append(key.status.success.res_path);
549 }
550
551 if (zcu_obj_path) |p| {
552 try argv.append(try p.toString(arena));
553 }
554
555 if (coff.module_definition_file) |def| {
556 try argv.append(try allocPrint(arena, "-DEF:{s}", .{def}));
557 }
558
559 const resolved_subsystem: ?std.Target.SubSystem = blk: {
560 if (coff.subsystem) |explicit| break :blk explicit;
561 switch (target.os.tag) {
562 .windows => {
563 if (comp.zcu != null) {
564 if (coff.lld_export_flags.dllmain_crt_startup or is_dyn_lib)
565 break :blk null;
566 if (coff.lld_export_flags.c_main or comp.config.is_test or
567 coff.lld_export_flags.winmain_crt_startup or
568 coff.lld_export_flags.wwinmain_crt_startup)
569 {
570 break :blk .Console;
571 }
572 if (coff.lld_export_flags.winmain or coff.lld_export_flags.wwinmain)
573 break :blk .Windows;
574 }
575 },
576 .uefi => break :blk .EfiApplication,
577 else => {},
578 }
579 break :blk null;
580 };
581
582 const Mode = enum { uefi, win32 };
583 const mode: Mode = mode: {
584 if (resolved_subsystem) |subsystem| {
585 const subsystem_suffix = try allocPrint(arena, ",{d}.{d}", .{
586 coff.major_subsystem_version, coff.minor_subsystem_version,
587 });
588
589 switch (subsystem) {
590 .Console => {
591 try argv.append(try allocPrint(arena, "-SUBSYSTEM:console{s}", .{
592 subsystem_suffix,
593 }));
594 break :mode .win32;
595 },
596 .EfiApplication => {
597 try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_application{s}", .{
598 subsystem_suffix,
599 }));
600 break :mode .uefi;
601 },
602 .EfiBootServiceDriver => {
603 try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_boot_service_driver{s}", .{
604 subsystem_suffix,
605 }));
606 break :mode .uefi;
607 },
608 .EfiRom => {
609 try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_rom{s}", .{
610 subsystem_suffix,
611 }));
612 break :mode .uefi;
613 },
614 .EfiRuntimeDriver => {
615 try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_runtime_driver{s}", .{
616 subsystem_suffix,
617 }));
618 break :mode .uefi;
619 },
620 .Native => {
621 try argv.append(try allocPrint(arena, "-SUBSYSTEM:native{s}", .{
622 subsystem_suffix,
623 }));
624 break :mode .win32;
625 },
626 .Posix => {
627 try argv.append(try allocPrint(arena, "-SUBSYSTEM:posix{s}", .{
628 subsystem_suffix,
629 }));
630 break :mode .win32;
631 },
632 .Windows => {
633 try argv.append(try allocPrint(arena, "-SUBSYSTEM:windows{s}", .{
634 subsystem_suffix,
635 }));
636 break :mode .win32;
637 },
638 }
639 } else if (target.os.tag == .uefi) {
640 break :mode .uefi;
641 } else {
642 break :mode .win32;
643 }
644 };
645
646 switch (mode) {
647 .uefi => try argv.appendSlice(&[_][]const u8{
648 "-BASE:0",
649 "-ENTRY:EfiMain",
650 "-OPT:REF",
651 "-SAFESEH:NO",
652 "-MERGE:.rdata=.data",
653 "-NODEFAULTLIB",
654 "-SECTION:.xdata,D",
655 }),
656 .win32 => {
657 if (link_in_crt) {
658 if (target.abi.isGnu()) {
659 if (target.cpu.arch == .x86) {
660 try argv.append("-ALTERNATENAME:__image_base__=___ImageBase");
661 } else {
662 try argv.append("-ALTERNATENAME:__image_base__=__ImageBase");
663 }
664
665 if (is_dyn_lib) {
666 try argv.append(try comp.crtFileAsString(arena, "dllcrt2.obj"));
667 if (target.cpu.arch == .x86) {
668 try argv.append("-ALTERNATENAME:__DllMainCRTStartup@12=_DllMainCRTStartup@12");
669 } else {
670 try argv.append("-ALTERNATENAME:_DllMainCRTStartup=DllMainCRTStartup");
671 }
672 } else {
673 try argv.append(try comp.crtFileAsString(arena, "crt2.obj"));
674 }
675
676 try argv.append(try comp.crtFileAsString(arena, "libmingw32.lib"));
677 } else {
678 try argv.append(switch (comp.config.link_mode) {
679 .static => "libcmt.lib",
680 .dynamic => "msvcrt.lib",
681 });
682
683 const lib_str = switch (comp.config.link_mode) {
684 .static => "lib",
685 .dynamic => "",
686 };
687 try argv.append(try allocPrint(arena, "{s}vcruntime.lib", .{lib_str}));
688 try argv.append(try allocPrint(arena, "{s}ucrt.lib", .{lib_str}));
689
690 //Visual C++ 2015 Conformance Changes
691 //https://msdn.microsoft.com/en-us/library/bb531344.aspx
692 try argv.append("legacy_stdio_definitions.lib");
693
694 // msvcrt depends on kernel32 and ntdll
695 try argv.append("kernel32.lib");
696 try argv.append("ntdll.lib");
697 }
698 } else {
699 try argv.append("-NODEFAULTLIB");
700 if (!is_lib and entry_name == null) {
701 if (comp.zcu != null) {
702 if (coff.lld_export_flags.winmain_crt_startup) {
703 try argv.append("-ENTRY:WinMainCRTStartup");
704 } else {
705 try argv.append("-ENTRY:wWinMainCRTStartup");
706 }
707 } else {
708 try argv.append("-ENTRY:wWinMainCRTStartup");
709 }
710 }
711 }
712 },
713 }
714
715 if (comp.config.link_libc and link_in_crt) {
716 if (comp.zigc_static_lib) |zigc| {
717 try argv.append(try zigc.full_object_path.toString(arena));
718 }
719 }
720
721 // libc++ dep
722 if (comp.config.link_libcpp) {
723 try argv.append(try comp.libcxxabi_static_lib.?.full_object_path.toString(arena));
724 try argv.append(try comp.libcxx_static_lib.?.full_object_path.toString(arena));
725 }
726
727 // libunwind dep
728 if (comp.config.link_libunwind) {
729 try argv.append(try comp.libunwind_static_lib.?.full_object_path.toString(arena));
730 }
731
732 if (comp.config.any_fuzz) {
733 try argv.append(try comp.fuzzer_lib.?.full_object_path.toString(arena));
734 }
735
736 const ubsan_rt_path: ?Cache.Path = blk: {
737 if (comp.ubsan_rt_lib) |x| break :blk x.full_object_path;
738 if (comp.ubsan_rt_obj) |x| break :blk x.full_object_path;
739 break :blk null;
740 };
741 if (ubsan_rt_path) |path| {
742 try argv.append(try path.toString(arena));
743 }
744
745 if (is_exe_or_dyn_lib and !comp.skip_linker_dependencies) {
746 // MSVC compiler_rt is missing some stuff, so we build it unconditionally but
747 // and rely on weak linkage to allow MSVC compiler_rt functions to override ours.
748 if (comp.compiler_rt_obj) |obj| try argv.append(try obj.full_object_path.toString(arena));
749 if (comp.compiler_rt_lib) |lib| try argv.append(try lib.full_object_path.toString(arena));
750 }
751
752 try argv.ensureUnusedCapacity(comp.windows_libs.count());
753 for (comp.windows_libs.keys()) |key| {
754 const lib_basename = try allocPrint(arena, "{s}.lib", .{key});
755 if (comp.crt_files.get(lib_basename)) |crt_file| {
756 argv.appendAssumeCapacity(try crt_file.full_object_path.toString(arena));
757 continue;
758 }
759 if (try findLib(arena, lib_basename, coff.lib_directories)) |full_path| {
760 argv.appendAssumeCapacity(full_path);
761 continue;
762 }
763 if (target.abi.isGnu()) {
764 const fallback_name = try allocPrint(arena, "lib{s}.dll.a", .{key});
765 if (try findLib(arena, fallback_name, coff.lib_directories)) |full_path| {
766 argv.appendAssumeCapacity(full_path);
767 continue;
768 }
769 }
770 if (target.abi == .msvc or target.abi == .itanium) {
771 argv.appendAssumeCapacity(lib_basename);
772 continue;
773 }
774
775 log.err("DLL import library for -l{s} not found", .{key});
776 return error.DllImportLibraryNotFound;
777 }
778
779 try spawnLld(comp, arena, argv.items);
780 }
781}
782fn findLib(arena: Allocator, name: []const u8, lib_directories: []const Cache.Directory) !?[]const u8 {
783 for (lib_directories) |lib_directory| {
784 lib_directory.handle.access(name, .{}) catch |err| switch (err) {
785 error.FileNotFound => continue,
786 else => |e| return e,
787 };
788 return try lib_directory.join(arena, &.{name});
789 }
790 return null;
791}
792
793fn elfLink(lld: *Lld, arena: Allocator) !void {
794 const comp = lld.base.comp;
795 const gpa = comp.gpa;
796 const diags = &comp.link_diags;
797 const base = &lld.base;
798 const elf = &lld.ofmt.elf;
799
800 const directory = base.emit.root_dir; // Just an alias to make it shorter to type.
801 const full_out_path = try directory.join(arena, &[_][]const u8{base.emit.sub_path});
802
803 const zcu_obj_path: ?Cache.Path = if (comp.zcu != null) p: {
804 break :p try comp.resolveEmitPathFlush(arena, .temp, base.zcu_object_basename.?);
805 } else null;
806
807 const output_mode = comp.config.output_mode;
808 const is_obj = output_mode == .Obj;
809 const is_lib = output_mode == .Lib;
810 const link_mode = comp.config.link_mode;
811 const is_dyn_lib = link_mode == .dynamic and is_lib;
812 const is_exe_or_dyn_lib = is_dyn_lib or output_mode == .Exe;
813 const have_dynamic_linker = link_mode == .dynamic and is_exe_or_dyn_lib;
814 const target = comp.root_mod.resolved_target.result;
815 const compiler_rt_path: ?Cache.Path = blk: {
816 if (comp.compiler_rt_lib) |x| break :blk x.full_object_path;
817 if (comp.compiler_rt_obj) |x| break :blk x.full_object_path;
818 break :blk null;
819 };
820 const ubsan_rt_path: ?Cache.Path = blk: {
821 if (comp.ubsan_rt_lib) |x| break :blk x.full_object_path;
822 if (comp.ubsan_rt_obj) |x| break :blk x.full_object_path;
823 break :blk null;
824 };
825
826 // Due to a deficiency in LLD, we need to special-case BPF to a simple file
827 // copy when generating relocatables. Normally, we would expect `lld -r` to work.
828 // However, because LLD wants to resolve BPF relocations which it shouldn't, it fails
829 // before even generating the relocatable.
830 //
831 // For m68k, we go through this path because LLD doesn't support it yet, but LLVM can
832 // produce usable object files.
833 if (output_mode == .Obj and
834 (comp.config.lto != .none or
835 target.cpu.arch.isBpf() or
836 target.cpu.arch == .lanai or
837 target.cpu.arch == .m68k or
838 target.cpu.arch.isSPARC() or
839 target.cpu.arch == .ve or
840 target.cpu.arch == .xcore))
841 {
842 // In this case we must do a simple file copy
843 // here. TODO: think carefully about how we can avoid this redundant operation when doing
844 // build-obj. See also the corresponding TODO in linkAsArchive.
845 const the_object_path = blk: {
846 if (link.firstObjectInput(comp.link_inputs)) |obj| break :blk obj.path;
847
848 if (comp.c_object_table.count() != 0)
849 break :blk comp.c_object_table.keys()[0].status.success.object_path;
850
851 if (zcu_obj_path) |p|
852 break :blk p;
853
854 // TODO I think this is unreachable. Audit this situation when solving the above TODO
855 // regarding eliding redundant object -> object transformations.
856 return error.NoObjectsToLink;
857 };
858 try std.fs.Dir.copyFile(
859 the_object_path.root_dir.handle,
860 the_object_path.sub_path,
861 directory.handle,
862 base.emit.sub_path,
863 .{},
864 );
865 } else {
866 // Create an LLD command line and invoke it.
867 var argv = std.ArrayList([]const u8).init(gpa);
868 defer argv.deinit();
869 // We will invoke ourselves as a child process to gain access to LLD.
870 // This is necessary because LLD does not behave properly as a library -
871 // it calls exit() and does not reset all global data between invocations.
872 const linker_command = "ld.lld";
873 try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command });
874 if (is_obj) {
875 try argv.append("-r");
876 }
877
878 try argv.append("--error-limit=0");
879
880 if (comp.sysroot) |sysroot| {
881 try argv.append(try std.fmt.allocPrint(arena, "--sysroot={s}", .{sysroot}));
882 }
883
884 if (target_util.llvmMachineAbi(target)) |mabi| {
885 try argv.appendSlice(&.{
886 "-mllvm",
887 try std.fmt.allocPrint(arena, "-target-abi={s}", .{mabi}),
888 });
889 }
890
891 try argv.appendSlice(&.{
892 "-mllvm",
893 try std.fmt.allocPrint(arena, "-float-abi={s}", .{if (target.abi.float() == .hard) "hard" else "soft"}),
894 });
895
896 if (comp.config.lto != .none) {
897 switch (comp.root_mod.optimize_mode) {
898 .Debug => {},
899 .ReleaseSmall => try argv.append("--lto-O2"),
900 .ReleaseFast, .ReleaseSafe => try argv.append("--lto-O3"),
901 }
902 }
903 switch (comp.root_mod.optimize_mode) {
904 .Debug => {},
905 .ReleaseSmall => try argv.append("-O2"),
906 .ReleaseFast, .ReleaseSafe => try argv.append("-O3"),
907 }
908
909 if (elf.entry_name) |name| {
910 try argv.appendSlice(&.{ "--entry", name });
911 }
912
913 for (comp.force_undefined_symbols.keys()) |sym| {
914 try argv.append("-u");
915 try argv.append(sym);
916 }
917
918 switch (elf.hash_style) {
919 .gnu => try argv.append("--hash-style=gnu"),
920 .sysv => try argv.append("--hash-style=sysv"),
921 .both => {}, // this is the default
922 }
923
924 if (output_mode == .Exe) {
925 try argv.appendSlice(&.{
926 "-z",
927 try std.fmt.allocPrint(arena, "stack-size={d}", .{base.stack_size}),
928 });
929 }
930
931 switch (base.build_id) {
932 .none => try argv.append("--build-id=none"),
933 .fast, .uuid, .sha1, .md5 => try argv.append(try std.fmt.allocPrint(arena, "--build-id={s}", .{
934 @tagName(base.build_id),
935 })),
936 .hexstring => |hs| try argv.append(try std.fmt.allocPrint(arena, "--build-id=0x{s}", .{
937 std.fmt.fmtSliceHexLower(hs.toSlice()),
938 })),
939 }
940
941 try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{elf.image_base}));
942
943 if (elf.linker_script) |linker_script| {
944 try argv.append("-T");
945 try argv.append(linker_script);
946 }
947
948 if (elf.sort_section) |how| {
949 const arg = try std.fmt.allocPrint(arena, "--sort-section={s}", .{@tagName(how)});
950 try argv.append(arg);
951 }
952
953 if (base.gc_sections) {
954 try argv.append("--gc-sections");
955 }
956
957 if (base.print_gc_sections) {
958 try argv.append("--print-gc-sections");
959 }
960
961 if (elf.print_icf_sections) {
962 try argv.append("--print-icf-sections");
963 }
964
965 if (elf.print_map) {
966 try argv.append("--print-map");
967 }
968
969 if (comp.link_eh_frame_hdr) {
970 try argv.append("--eh-frame-hdr");
971 }
972
973 if (elf.emit_relocs) {
974 try argv.append("--emit-relocs");
975 }
976
977 if (comp.config.rdynamic) {
978 try argv.append("--export-dynamic");
979 }
980
981 if (comp.config.debug_format == .strip) {
982 try argv.append("-s");
983 }
984
985 if (elf.z_nodelete) {
986 try argv.append("-z");
987 try argv.append("nodelete");
988 }
989 if (elf.z_notext) {
990 try argv.append("-z");
991 try argv.append("notext");
992 }
993 if (elf.z_defs) {
994 try argv.append("-z");
995 try argv.append("defs");
996 }
997 if (elf.z_origin) {
998 try argv.append("-z");
999 try argv.append("origin");
1000 }
1001 if (elf.z_nocopyreloc) {
1002 try argv.append("-z");
1003 try argv.append("nocopyreloc");
1004 }
1005 if (elf.z_now) {
1006 // LLD defaults to -zlazy
1007 try argv.append("-znow");
1008 }
1009 if (!elf.z_relro) {
1010 // LLD defaults to -zrelro
1011 try argv.append("-znorelro");
1012 }
1013 if (elf.z_common_page_size) |size| {
1014 try argv.append("-z");
1015 try argv.append(try std.fmt.allocPrint(arena, "common-page-size={d}", .{size}));
1016 }
1017 if (elf.z_max_page_size) |size| {
1018 try argv.append("-z");
1019 try argv.append(try std.fmt.allocPrint(arena, "max-page-size={d}", .{size}));
1020 }
1021
1022 if (getLDMOption(target)) |ldm| {
1023 try argv.append("-m");
1024 try argv.append(ldm);
1025 }
1026
1027 if (link_mode == .static) {
1028 if (target.cpu.arch.isArm()) {
1029 try argv.append("-Bstatic");
1030 } else {
1031 try argv.append("-static");
1032 }
1033 } else if (switch (target.os.tag) {
1034 else => is_dyn_lib,
1035 .haiku => is_exe_or_dyn_lib,
1036 }) {
1037 try argv.append("-shared");
1038 }
1039
1040 if (comp.config.pie and output_mode == .Exe) {
1041 try argv.append("-pie");
1042 }
1043
1044 if (is_exe_or_dyn_lib and target.os.tag == .netbsd) {
1045 // Add options to produce shared objects with only 2 PT_LOAD segments.
1046 // NetBSD expects 2 PT_LOAD segments in a shared object, otherwise
1047 // ld.elf_so fails loading dynamic libraries with "not found" error.
1048 // See https://github.com/ziglang/zig/issues/9109 .
1049 try argv.append("--no-rosegment");
1050 try argv.append("-znorelro");
1051 }
1052
1053 try argv.append("-o");
1054 try argv.append(full_out_path);
1055
1056 // csu prelude
1057 const csu = try comp.getCrtPaths(arena);
1058 if (csu.crt0) |p| try argv.append(try p.toString(arena));
1059 if (csu.crti) |p| try argv.append(try p.toString(arena));
1060 if (csu.crtbegin) |p| try argv.append(try p.toString(arena));
1061
1062 for (elf.rpath_list) |rpath| {
1063 try argv.appendSlice(&.{ "-rpath", rpath });
1064 }
1065
1066 for (elf.symbol_wrap_set) |symbol_name| {
1067 try argv.appendSlice(&.{ "-wrap", symbol_name });
1068 }
1069
1070 if (comp.config.link_libc) {
1071 if (comp.libc_installation) |libc_installation| {
1072 try argv.append("-L");
1073 try argv.append(libc_installation.crt_dir.?);
1074 }
1075 }
1076
1077 if (have_dynamic_linker and
1078 (comp.config.link_libc or comp.root_mod.resolved_target.is_explicit_dynamic_linker))
1079 {
1080 if (target.dynamic_linker.get()) |dynamic_linker| {
1081 try argv.append("-dynamic-linker");
1082 try argv.append(dynamic_linker);
1083 }
1084 }
1085
1086 if (is_dyn_lib) {
1087 if (elf.soname) |soname| {
1088 try argv.append("-soname");
1089 try argv.append(soname);
1090 }
1091 if (elf.version_script) |version_script| {
1092 try argv.append("-version-script");
1093 try argv.append(version_script);
1094 }
1095 if (elf.allow_undefined_version) {
1096 try argv.append("--undefined-version");
1097 } else {
1098 try argv.append("--no-undefined-version");
1099 }
1100 if (elf.enable_new_dtags) |enable_new_dtags| {
1101 if (enable_new_dtags) {
1102 try argv.append("--enable-new-dtags");
1103 } else {
1104 try argv.append("--disable-new-dtags");
1105 }
1106 }
1107 }
1108
1109 // Positional arguments to the linker such as object files.
1110 var whole_archive = false;
1111
1112 for (base.comp.link_inputs) |link_input| switch (link_input) {
1113 .res => unreachable, // Windows-only
1114 .dso => continue,
1115 .object, .archive => |obj| {
1116 if (obj.must_link and !whole_archive) {
1117 try argv.append("-whole-archive");
1118 whole_archive = true;
1119 } else if (!obj.must_link and whole_archive) {
1120 try argv.append("-no-whole-archive");
1121 whole_archive = false;
1122 }
1123 try argv.append(try obj.path.toString(arena));
1124 },
1125 .dso_exact => |dso_exact| {
1126 assert(dso_exact.name[0] == ':');
1127 try argv.appendSlice(&.{ "-l", dso_exact.name });
1128 },
1129 };
1130
1131 if (whole_archive) {
1132 try argv.append("-no-whole-archive");
1133 whole_archive = false;
1134 }
1135
1136 for (comp.c_object_table.keys()) |key| {
1137 try argv.append(try key.status.success.object_path.toString(arena));
1138 }
1139
1140 if (zcu_obj_path) |p| {
1141 try argv.append(try p.toString(arena));
1142 }
1143
1144 if (comp.tsan_lib) |lib| {
1145 assert(comp.config.any_sanitize_thread);
1146 try argv.append(try lib.full_object_path.toString(arena));
1147 }
1148
1149 if (comp.fuzzer_lib) |lib| {
1150 assert(comp.config.any_fuzz);
1151 try argv.append(try lib.full_object_path.toString(arena));
1152 }
1153
1154 if (ubsan_rt_path) |p| {
1155 try argv.append(try p.toString(arena));
1156 }
1157
1158 // Shared libraries.
1159 if (is_exe_or_dyn_lib) {
1160 // Worst-case, we need an --as-needed argument for every lib, as well
1161 // as one before and one after.
1162 try argv.ensureUnusedCapacity(2 * base.comp.link_inputs.len + 2);
1163 argv.appendAssumeCapacity("--as-needed");
1164 var as_needed = true;
1165
1166 for (base.comp.link_inputs) |link_input| switch (link_input) {
1167 .res => unreachable, // Windows-only
1168 .object, .archive, .dso_exact => continue,
1169 .dso => |dso| {
1170 const lib_as_needed = !dso.needed;
1171 switch ((@as(u2, @intFromBool(lib_as_needed)) << 1) | @intFromBool(as_needed)) {
1172 0b00, 0b11 => {},
1173 0b01 => {
1174 argv.appendAssumeCapacity("--no-as-needed");
1175 as_needed = false;
1176 },
1177 0b10 => {
1178 argv.appendAssumeCapacity("--as-needed");
1179 as_needed = true;
1180 },
1181 }
1182
1183 // By this time, we depend on these libs being dynamically linked
1184 // libraries and not static libraries (the check for that needs to be earlier),
1185 // but they could be full paths to .so files, in which case we
1186 // want to avoid prepending "-l".
1187 argv.appendAssumeCapacity(try dso.path.toString(arena));
1188 },
1189 };
1190
1191 if (!as_needed) {
1192 argv.appendAssumeCapacity("--as-needed");
1193 as_needed = true;
1194 }
1195
1196 // libc++ dep
1197 if (comp.config.link_libcpp) {
1198 try argv.append(try comp.libcxxabi_static_lib.?.full_object_path.toString(arena));
1199 try argv.append(try comp.libcxx_static_lib.?.full_object_path.toString(arena));
1200 }
1201
1202 // libunwind dep
1203 if (comp.config.link_libunwind) {
1204 try argv.append(try comp.libunwind_static_lib.?.full_object_path.toString(arena));
1205 }
1206
1207 // libc dep
1208 diags.flags.missing_libc = false;
1209 if (comp.config.link_libc) {
1210 if (comp.libc_installation != null) {
1211 const needs_grouping = link_mode == .static;
1212 if (needs_grouping) try argv.append("--start-group");
1213 try argv.appendSlice(target_util.libcFullLinkFlags(target));
1214 if (needs_grouping) try argv.append("--end-group");
1215 } else if (target.isGnuLibC()) {
1216 for (glibc.libs) |lib| {
1217 if (lib.removed_in) |rem_in| {
1218 if (target.os.versionRange().gnuLibCVersion().?.order(rem_in) != .lt) continue;
1219 }
1220
1221 const lib_path = try std.fmt.allocPrint(arena, "{}{c}lib{s}.so.{d}", .{
1222 comp.glibc_so_files.?.dir_path, fs.path.sep, lib.name, lib.sover,
1223 });
1224 try argv.append(lib_path);
1225 }
1226 try argv.append(try comp.crtFileAsString(arena, "libc_nonshared.a"));
1227 } else if (target.isMuslLibC()) {
1228 try argv.append(try comp.crtFileAsString(arena, switch (link_mode) {
1229 .static => "libc.a",
1230 .dynamic => "libc.so",
1231 }));
1232 } else if (target.isFreeBSDLibC()) {
1233 for (freebsd.libs) |lib| {
1234 const lib_path = try std.fmt.allocPrint(arena, "{}{c}lib{s}.so.{d}", .{
1235 comp.freebsd_so_files.?.dir_path, fs.path.sep, lib.name, lib.sover,
1236 });
1237 try argv.append(lib_path);
1238 }
1239 } else if (target.isNetBSDLibC()) {
1240 for (netbsd.libs) |lib| {
1241 const lib_path = try std.fmt.allocPrint(arena, "{}{c}lib{s}.so.{d}", .{
1242 comp.netbsd_so_files.?.dir_path, fs.path.sep, lib.name, lib.sover,
1243 });
1244 try argv.append(lib_path);
1245 }
1246 } else {
1247 diags.flags.missing_libc = true;
1248 }
1249
1250 if (comp.zigc_static_lib) |zigc| {
1251 try argv.append(try zigc.full_object_path.toString(arena));
1252 }
1253 }
1254 }
1255
1256 // compiler-rt. Since compiler_rt exports symbols like `memset`, it needs
1257 // to be after the shared libraries, so they are picked up from the shared
1258 // libraries, not libcompiler_rt.
1259 if (compiler_rt_path) |p| {
1260 try argv.append(try p.toString(arena));
1261 }
1262
1263 // crt postlude
1264 if (csu.crtend) |p| try argv.append(try p.toString(arena));
1265 if (csu.crtn) |p| try argv.append(try p.toString(arena));
1266
1267 if (base.allow_shlib_undefined) {
1268 try argv.append("--allow-shlib-undefined");
1269 }
1270
1271 switch (elf.compress_debug_sections) {
1272 .none => {},
1273 .zlib => try argv.append("--compress-debug-sections=zlib"),
1274 .zstd => try argv.append("--compress-debug-sections=zstd"),
1275 }
1276
1277 if (elf.bind_global_refs_locally) {
1278 try argv.append("-Bsymbolic");
1279 }
1280
1281 try spawnLld(comp, arena, argv.items);
1282 }
1283}
1284fn getLDMOption(target: std.Target) ?[]const u8 {
1285 // This should only return emulations understood by LLD's parseEmulation().
1286 return switch (target.cpu.arch) {
1287 .aarch64 => switch (target.os.tag) {
1288 .linux => "aarch64linux",
1289 else => "aarch64elf",
1290 },
1291 .aarch64_be => switch (target.os.tag) {
1292 .linux => "aarch64linuxb",
1293 else => "aarch64elfb",
1294 },
1295 .amdgcn => "elf64_amdgpu",
1296 .arm, .thumb => switch (target.os.tag) {
1297 .linux => "armelf_linux_eabi",
1298 else => "armelf",
1299 },
1300 .armeb, .thumbeb => switch (target.os.tag) {
1301 .linux => "armelfb_linux_eabi",
1302 else => "armelfb",
1303 },
1304 .hexagon => "hexagonelf",
1305 .loongarch32 => "elf32loongarch",
1306 .loongarch64 => "elf64loongarch",
1307 .mips => switch (target.os.tag) {
1308 .freebsd => "elf32btsmip_fbsd",
1309 else => "elf32btsmip",
1310 },
1311 .mipsel => switch (target.os.tag) {
1312 .freebsd => "elf32ltsmip_fbsd",
1313 else => "elf32ltsmip",
1314 },
1315 .mips64 => switch (target.os.tag) {
1316 .freebsd => switch (target.abi) {
1317 .gnuabin32, .muslabin32 => "elf32btsmipn32_fbsd",
1318 else => "elf64btsmip_fbsd",
1319 },
1320 else => switch (target.abi) {
1321 .gnuabin32, .muslabin32 => "elf32btsmipn32",
1322 else => "elf64btsmip",
1323 },
1324 },
1325 .mips64el => switch (target.os.tag) {
1326 .freebsd => switch (target.abi) {
1327 .gnuabin32, .muslabin32 => "elf32ltsmipn32_fbsd",
1328 else => "elf64ltsmip_fbsd",
1329 },
1330 else => switch (target.abi) {
1331 .gnuabin32, .muslabin32 => "elf32ltsmipn32",
1332 else => "elf64ltsmip",
1333 },
1334 },
1335 .msp430 => "msp430elf",
1336 .powerpc => switch (target.os.tag) {
1337 .freebsd => "elf32ppc_fbsd",
1338 .linux => "elf32ppclinux",
1339 else => "elf32ppc",
1340 },
1341 .powerpcle => switch (target.os.tag) {
1342 .linux => "elf32lppclinux",
1343 else => "elf32lppc",
1344 },
1345 .powerpc64 => "elf64ppc",
1346 .powerpc64le => "elf64lppc",
1347 .riscv32 => "elf32lriscv",
1348 .riscv64 => "elf64lriscv",
1349 .s390x => "elf64_s390",
1350 .sparc64 => "elf64_sparc",
1351 .x86 => switch (target.os.tag) {
1352 .freebsd => "elf_i386_fbsd",
1353 else => "elf_i386",
1354 },
1355 .x86_64 => switch (target.abi) {
1356 .gnux32, .muslx32 => "elf32_x86_64",
1357 else => "elf_x86_64",
1358 },
1359 else => null,
1360 };
1361}
1362fn wasmLink(lld: *Lld, arena: Allocator) !void {
1363 const comp = lld.base.comp;
1364 const shared_memory = comp.config.shared_memory;
1365 const export_memory = comp.config.export_memory;
1366 const import_memory = comp.config.import_memory;
1367 const target = comp.root_mod.resolved_target.result;
1368 const base = &lld.base;
1369 const wasm = &lld.ofmt.wasm;
1370
1371 const gpa = comp.gpa;
1372
1373 const directory = base.emit.root_dir; // Just an alias to make it shorter to type.
1374 const full_out_path = try directory.join(arena, &[_][]const u8{base.emit.sub_path});
1375
1376 const zcu_obj_path: ?Cache.Path = if (comp.zcu != null) p: {
1377 break :p try comp.resolveEmitPathFlush(arena, .temp, base.zcu_object_basename.?);
1378 } else null;
1379
1380 const is_obj = comp.config.output_mode == .Obj;
1381 const compiler_rt_path: ?Cache.Path = blk: {
1382 if (comp.compiler_rt_lib) |lib| break :blk lib.full_object_path;
1383 if (comp.compiler_rt_obj) |obj| break :blk obj.full_object_path;
1384 break :blk null;
1385 };
1386 const ubsan_rt_path: ?Cache.Path = blk: {
1387 if (comp.ubsan_rt_lib) |lib| break :blk lib.full_object_path;
1388 if (comp.ubsan_rt_obj) |obj| break :blk obj.full_object_path;
1389 break :blk null;
1390 };
1391
1392 if (is_obj) {
1393 // LLD's WASM driver does not support the equivalent of `-r` so we do a simple file copy
1394 // here. TODO: think carefully about how we can avoid this redundant operation when doing
1395 // build-obj. See also the corresponding TODO in linkAsArchive.
1396 const the_object_path = blk: {
1397 if (link.firstObjectInput(comp.link_inputs)) |obj| break :blk obj.path;
1398
1399 if (comp.c_object_table.count() != 0)
1400 break :blk comp.c_object_table.keys()[0].status.success.object_path;
1401
1402 if (zcu_obj_path) |p|
1403 break :blk p;
1404
1405 // TODO I think this is unreachable. Audit this situation when solving the above TODO
1406 // regarding eliding redundant object -> object transformations.
1407 return error.NoObjectsToLink;
1408 };
1409 try fs.Dir.copyFile(
1410 the_object_path.root_dir.handle,
1411 the_object_path.sub_path,
1412 directory.handle,
1413 base.emit.sub_path,
1414 .{},
1415 );
1416 } else {
1417 // Create an LLD command line and invoke it.
1418 var argv = std.ArrayList([]const u8).init(gpa);
1419 defer argv.deinit();
1420 // We will invoke ourselves as a child process to gain access to LLD.
1421 // This is necessary because LLD does not behave properly as a library -
1422 // it calls exit() and does not reset all global data between invocations.
1423 const linker_command = "wasm-ld";
1424 try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command });
1425 try argv.append("--error-limit=0");
1426
1427 if (comp.config.lto != .none) {
1428 switch (comp.root_mod.optimize_mode) {
1429 .Debug => {},
1430 .ReleaseSmall => try argv.append("-O2"),
1431 .ReleaseFast, .ReleaseSafe => try argv.append("-O3"),
1432 }
1433 }
1434
1435 if (import_memory) {
1436 try argv.append("--import-memory");
1437 }
1438
1439 if (export_memory) {
1440 try argv.append("--export-memory");
1441 }
1442
1443 if (wasm.import_table) {
1444 assert(!wasm.export_table);
1445 try argv.append("--import-table");
1446 }
1447
1448 if (wasm.export_table) {
1449 assert(!wasm.import_table);
1450 try argv.append("--export-table");
1451 }
1452
1453 // For wasm-ld we only need to specify '--no-gc-sections' when the user explicitly
1454 // specified it as garbage collection is enabled by default.
1455 if (!base.gc_sections) {
1456 try argv.append("--no-gc-sections");
1457 }
1458
1459 if (comp.config.debug_format == .strip) {
1460 try argv.append("-s");
1461 }
1462
1463 if (wasm.initial_memory) |initial_memory| {
1464 const arg = try std.fmt.allocPrint(arena, "--initial-memory={d}", .{initial_memory});
1465 try argv.append(arg);
1466 }
1467
1468 if (wasm.max_memory) |max_memory| {
1469 const arg = try std.fmt.allocPrint(arena, "--max-memory={d}", .{max_memory});
1470 try argv.append(arg);
1471 }
1472
1473 if (shared_memory) {
1474 try argv.append("--shared-memory");
1475 }
1476
1477 if (wasm.global_base) |global_base| {
1478 const arg = try std.fmt.allocPrint(arena, "--global-base={d}", .{global_base});
1479 try argv.append(arg);
1480 } else {
1481 // We prepend it by default, so when a stack overflow happens the runtime will trap correctly,
1482 // rather than silently overwrite all global declarations. See https://github.com/ziglang/zig/issues/4496
1483 //
1484 // The user can overwrite this behavior by setting the global-base
1485 try argv.append("--stack-first");
1486 }
1487
1488 // Users are allowed to specify which symbols they want to export to the wasm host.
1489 for (wasm.export_symbol_names) |symbol_name| {
1490 const arg = try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name});
1491 try argv.append(arg);
1492 }
1493
1494 if (comp.config.rdynamic) {
1495 try argv.append("--export-dynamic");
1496 }
1497
1498 if (wasm.entry_name) |entry_name| {
1499 try argv.appendSlice(&.{ "--entry", entry_name });
1500 } else {
1501 try argv.append("--no-entry");
1502 }
1503
1504 try argv.appendSlice(&.{
1505 "-z",
1506 try std.fmt.allocPrint(arena, "stack-size={d}", .{base.stack_size}),
1507 });
1508
1509 switch (base.build_id) {
1510 .none => try argv.append("--build-id=none"),
1511 .fast, .uuid, .sha1 => try argv.append(try std.fmt.allocPrint(arena, "--build-id={s}", .{
1512 @tagName(base.build_id),
1513 })),
1514 .hexstring => |hs| try argv.append(try std.fmt.allocPrint(arena, "--build-id=0x{s}", .{
1515 std.fmt.fmtSliceHexLower(hs.toSlice()),
1516 })),
1517 .md5 => {},
1518 }
1519
1520 if (wasm.import_symbols) {
1521 try argv.append("--allow-undefined");
1522 }
1523
1524 if (comp.config.output_mode == .Lib and comp.config.link_mode == .dynamic) {
1525 try argv.append("--shared");
1526 }
1527 if (comp.config.pie) {
1528 try argv.append("--pie");
1529 }
1530
1531 try argv.appendSlice(&.{ "-o", full_out_path });
1532
1533 if (target.cpu.arch == .wasm64) {
1534 try argv.append("-mwasm64");
1535 }
1536
1537 const is_exe_or_dyn_lib = comp.config.output_mode == .Exe or
1538 (comp.config.output_mode == .Lib and comp.config.link_mode == .dynamic);
1539
1540 if (comp.config.link_libc and is_exe_or_dyn_lib) {
1541 if (target.os.tag == .wasi) {
1542 for (comp.wasi_emulated_libs) |crt_file| {
1543 try argv.append(try comp.crtFileAsString(
1544 arena,
1545 wasi_libc.emulatedLibCRFileLibName(crt_file),
1546 ));
1547 }
1548
1549 try argv.append(try comp.crtFileAsString(
1550 arena,
1551 wasi_libc.execModelCrtFileFullName(comp.config.wasi_exec_model),
1552 ));
1553 try argv.append(try comp.crtFileAsString(arena, "libc.a"));
1554 }
1555
1556 if (comp.zigc_static_lib) |zigc| {
1557 try argv.append(try zigc.full_object_path.toString(arena));
1558 }
1559
1560 if (comp.config.link_libcpp) {
1561 try argv.append(try comp.libcxx_static_lib.?.full_object_path.toString(arena));
1562 try argv.append(try comp.libcxxabi_static_lib.?.full_object_path.toString(arena));
1563 }
1564 }
1565
1566 // Positional arguments to the linker such as object files.
1567 var whole_archive = false;
1568 for (comp.link_inputs) |link_input| switch (link_input) {
1569 .object, .archive => |obj| {
1570 if (obj.must_link and !whole_archive) {
1571 try argv.append("-whole-archive");
1572 whole_archive = true;
1573 } else if (!obj.must_link and whole_archive) {
1574 try argv.append("-no-whole-archive");
1575 whole_archive = false;
1576 }
1577 try argv.append(try obj.path.toString(arena));
1578 },
1579 .dso => |dso| {
1580 try argv.append(try dso.path.toString(arena));
1581 },
1582 .dso_exact => unreachable,
1583 .res => unreachable,
1584 };
1585 if (whole_archive) {
1586 try argv.append("-no-whole-archive");
1587 whole_archive = false;
1588 }
1589
1590 for (comp.c_object_table.keys()) |key| {
1591 try argv.append(try key.status.success.object_path.toString(arena));
1592 }
1593 if (zcu_obj_path) |p| {
1594 try argv.append(try p.toString(arena));
1595 }
1596
1597 if (compiler_rt_path) |p| {
1598 try argv.append(try p.toString(arena));
1599 }
1600
1601 if (ubsan_rt_path) |p| {
1602 try argv.append(try p.toStringZ(arena));
1603 }
1604
1605 try spawnLld(comp, arena, argv.items);
1606
1607 // Give +x to the .wasm file if it is an executable and the OS is WASI.
1608 // Some systems may be configured to execute such binaries directly. Even if that
1609 // is not the case, it means we will get "exec format error" when trying to run
1610 // it, and then can react to that in the same way as trying to run an ELF file
1611 // from a foreign CPU architecture.
1612 if (fs.has_executable_bit and target.os.tag == .wasi and
1613 comp.config.output_mode == .Exe)
1614 {
1615 // TODO: what's our strategy for reporting linker errors from this function?
1616 // report a nice error here with the file path if it fails instead of
1617 // just returning the error code.
1618 // chmod does not interact with umask, so we use a conservative -rwxr--r-- here.
1619 std.posix.fchmodat(fs.cwd().fd, full_out_path, 0o744, 0) catch |err| switch (err) {
1620 error.OperationNotSupported => unreachable, // Not a symlink.
1621 else => |e| return e,
1622 };
1623 }
1624 }
1625}
1626
1627fn spawnLld(
1628 comp: *Compilation,
1629 arena: Allocator,
1630 argv: []const []const u8,
1631) !void {
1632 if (comp.verbose_link) {
1633 // Skip over our own name so that the LLD linker name is the first argv item.
1634 Compilation.dump_argv(argv[1..]);
1635 }
1636
1637 // If possible, we run LLD as a child process because it does not always
1638 // behave properly as a library, unfortunately.
1639 // https://github.com/ziglang/zig/issues/3825
1640 if (!std.process.can_spawn) {
1641 const exit_code = try lldMain(arena, argv, false);
1642 if (exit_code == 0) return;
1643 if (comp.clang_passthrough_mode) std.process.exit(exit_code);
1644 return error.LinkFailure;
1645 }
1646
1647 var stderr: []u8 = &.{};
1648 defer comp.gpa.free(stderr);
1649
1650 var child = std.process.Child.init(argv, arena);
1651 const term = (if (comp.clang_passthrough_mode) term: {
1652 child.stdin_behavior = .Inherit;
1653 child.stdout_behavior = .Inherit;
1654 child.stderr_behavior = .Inherit;
1655
1656 break :term child.spawnAndWait();
1657 } else term: {
1658 child.stdin_behavior = .Ignore;
1659 child.stdout_behavior = .Ignore;
1660 child.stderr_behavior = .Pipe;
1661
1662 child.spawn() catch |err| break :term err;
1663 stderr = try child.stderr.?.reader().readAllAlloc(comp.gpa, std.math.maxInt(usize));
1664 break :term child.wait();
1665 }) catch |first_err| term: {
1666 const err = switch (first_err) {
1667 error.NameTooLong => err: {
1668 const s = fs.path.sep_str;
1669 const rand_int = std.crypto.random.int(u64);
1670 const rsp_path = "tmp" ++ s ++ std.fmt.hex(rand_int) ++ ".rsp";
1671
1672 const rsp_file = try comp.dirs.local_cache.handle.createFileZ(rsp_path, .{});
1673 defer comp.dirs.local_cache.handle.deleteFileZ(rsp_path) catch |err|
1674 log.warn("failed to delete response file {s}: {s}", .{ rsp_path, @errorName(err) });
1675 {
1676 defer rsp_file.close();
1677 var rsp_buf = std.io.bufferedWriter(rsp_file.writer());
1678 const rsp_writer = rsp_buf.writer();
1679 for (argv[2..]) |arg| {
1680 try rsp_writer.writeByte('"');
1681 for (arg) |c| {
1682 switch (c) {
1683 '\"', '\\' => try rsp_writer.writeByte('\\'),
1684 else => {},
1685 }
1686 try rsp_writer.writeByte(c);
1687 }
1688 try rsp_writer.writeByte('"');
1689 try rsp_writer.writeByte('\n');
1690 }
1691 try rsp_buf.flush();
1692 }
1693
1694 var rsp_child = std.process.Child.init(&.{ argv[0], argv[1], try std.fmt.allocPrint(
1695 arena,
1696 "@{s}",
1697 .{try comp.dirs.local_cache.join(arena, &.{rsp_path})},
1698 ) }, arena);
1699 if (comp.clang_passthrough_mode) {
1700 rsp_child.stdin_behavior = .Inherit;
1701 rsp_child.stdout_behavior = .Inherit;
1702 rsp_child.stderr_behavior = .Inherit;
1703
1704 break :term rsp_child.spawnAndWait() catch |err| break :err err;
1705 } else {
1706 rsp_child.stdin_behavior = .Ignore;
1707 rsp_child.stdout_behavior = .Ignore;
1708 rsp_child.stderr_behavior = .Pipe;
1709
1710 rsp_child.spawn() catch |err| break :err err;
1711 stderr = try rsp_child.stderr.?.reader().readAllAlloc(comp.gpa, std.math.maxInt(usize));
1712 break :term rsp_child.wait() catch |err| break :err err;
1713 }
1714 },
1715 else => first_err,
1716 };
1717 log.err("unable to spawn LLD {s}: {s}", .{ argv[0], @errorName(err) });
1718 return error.UnableToSpawnSelf;
1719 };
1720
1721 const diags = &comp.link_diags;
1722 switch (term) {
1723 .Exited => |code| if (code != 0) {
1724 if (comp.clang_passthrough_mode) std.process.exit(code);
1725 diags.lockAndParseLldStderr(argv[1], stderr);
1726 return error.LinkFailure;
1727 },
1728 else => {
1729 if (comp.clang_passthrough_mode) std.process.abort();
1730 return diags.fail("{s} terminated with stderr:\n{s}", .{ argv[0], stderr });
1731 },
1732 }
1733
1734 if (stderr.len > 0) log.warn("unexpected LLD stderr:\n{s}", .{stderr});
1735}
1736
1737const std = @import("std");
1738const Allocator = std.mem.Allocator;
1739const Cache = std.Build.Cache;
1740const allocPrint = std.fmt.allocPrint;
1741const assert = std.debug.assert;
1742const fs = std.fs;
1743const log = std.log.scoped(.link);
1744const mem = std.mem;
1745
1746const Compilation = @import("../Compilation.zig");
1747const Zcu = @import("../Zcu.zig");
1748const dev = @import("../dev.zig");
1749const freebsd = @import("../libs/freebsd.zig");
1750const glibc = @import("../libs/glibc.zig");
1751const netbsd = @import("../libs/netbsd.zig");
1752const wasi_libc = @import("../libs/wasi_libc.zig");
1753const link = @import("../link.zig");
1754const lldMain = @import("../main.zig").lldMain;
1755const target_util = @import("../target.zig");
1756const trace = @import("../tracy.zig").trace;
1757const Lld = @This();
src/link/MachO.zig+19-64
...@@ -6,9 +6,6 @@ base: link.File,...@@ -6,9 +6,6 @@ base: link.File,
66
7rpath_list: []const []const u8,7rpath_list: []const []const u8,
88
9/// If this is not null, an object file is created by LLVM and emitted to zcu_object_sub_path.
10llvm_object: ?LlvmObject.Ptr = null,
11
12/// Debug symbols bundle (or dSym).9/// Debug symbols bundle (or dSym).
13d_sym: ?DebugSymbols = null,10d_sym: ?DebugSymbols = null,
1411
...@@ -176,13 +173,6 @@ pub fn createEmpty(...@@ -176,13 +173,6 @@ pub fn createEmpty(
176 const output_mode = comp.config.output_mode;173 const output_mode = comp.config.output_mode;
177 const link_mode = comp.config.link_mode;174 const link_mode = comp.config.link_mode;
178175
179 // If using LLVM to generate the object file for the zig compilation unit,
180 // we need a place to put the object file so that it can be subsequently
181 // handled.
182 const zcu_object_sub_path = if (!use_llvm)
183 null
184 else
185 try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path});
186 const allow_shlib_undefined = options.allow_shlib_undefined orelse false;176 const allow_shlib_undefined = options.allow_shlib_undefined orelse false;
187177
188 const self = try arena.create(MachO);178 const self = try arena.create(MachO);
...@@ -191,13 +181,15 @@ pub fn createEmpty(...@@ -191,13 +181,15 @@ pub fn createEmpty(
191 .tag = .macho,181 .tag = .macho,
192 .comp = comp,182 .comp = comp,
193 .emit = emit,183 .emit = emit,
194 .zcu_object_sub_path = zcu_object_sub_path,184 .zcu_object_basename = if (use_llvm)
185 try std.fmt.allocPrint(arena, "{s}_zcu.o", .{fs.path.stem(emit.sub_path)})
186 else
187 null,
195 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug),188 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug),
196 .print_gc_sections = options.print_gc_sections,189 .print_gc_sections = options.print_gc_sections,
197 .stack_size = options.stack_size orelse 16777216,190 .stack_size = options.stack_size orelse 16777216,
198 .allow_shlib_undefined = allow_shlib_undefined,191 .allow_shlib_undefined = allow_shlib_undefined,
199 .file = null,192 .file = null,
200 .disable_lld_caching = options.disable_lld_caching,
201 .build_id = options.build_id,193 .build_id = options.build_id,
202 },194 },
203 .rpath_list = options.rpath_list,195 .rpath_list = options.rpath_list,
...@@ -225,15 +217,12 @@ pub fn createEmpty(...@@ -225,15 +217,12 @@ pub fn createEmpty(
225 .force_load_objc = options.force_load_objc,217 .force_load_objc = options.force_load_objc,
226 .discard_local_symbols = options.discard_local_symbols,218 .discard_local_symbols = options.discard_local_symbols,
227 };219 };
228 if (use_llvm and comp.config.have_zcu) {
229 self.llvm_object = try LlvmObject.create(arena, comp);
230 }
231 errdefer self.base.destroy();220 errdefer self.base.destroy();
232221
233 self.base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{222 self.base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{
234 .truncate = true,223 .truncate = true,
235 .read = true,224 .read = true,
236 .mode = link.File.determineMode(false, output_mode, link_mode),225 .mode = link.File.determineMode(output_mode, link_mode),
237 });226 });
238227
239 // Append null file228 // Append null file
...@@ -280,8 +269,6 @@ pub fn open(...@@ -280,8 +269,6 @@ pub fn open(
280pub fn deinit(self: *MachO) void {269pub fn deinit(self: *MachO) void {
281 const gpa = self.base.comp.gpa;270 const gpa = self.base.comp.gpa;
282271
283 if (self.llvm_object) |llvm_object| llvm_object.deinit();
284
285 if (self.d_sym) |*d_sym| {272 if (self.d_sym) |*d_sym| {
286 d_sym.deinit();273 d_sym.deinit();
287 }274 }
...@@ -349,15 +336,6 @@ pub fn flush(...@@ -349,15 +336,6 @@ pub fn flush(
349 arena: Allocator,336 arena: Allocator,
350 tid: Zcu.PerThread.Id,337 tid: Zcu.PerThread.Id,
351 prog_node: std.Progress.Node,338 prog_node: std.Progress.Node,
352) link.File.FlushError!void {
353 try self.flushModule(arena, tid, prog_node);
354}
355
356pub fn flushModule(
357 self: *MachO,
358 arena: Allocator,
359 tid: Zcu.PerThread.Id,
360 prog_node: std.Progress.Node,
361) link.File.FlushError!void {339) link.File.FlushError!void {
362 const tracy = trace(@src());340 const tracy = trace(@src());
363 defer tracy.end();341 defer tracy.end();
...@@ -366,28 +344,19 @@ pub fn flushModule(...@@ -366,28 +344,19 @@ pub fn flushModule(
366 const gpa = comp.gpa;344 const gpa = comp.gpa;
367 const diags = &self.base.comp.link_diags;345 const diags = &self.base.comp.link_diags;
368346
369 if (self.llvm_object) |llvm_object| {
370 try self.base.emitLlvmObject(arena, llvm_object, prog_node);
371 }
372
373 const sub_prog_node = prog_node.start("MachO Flush", 0);347 const sub_prog_node = prog_node.start("MachO Flush", 0);
374 defer sub_prog_node.end();348 defer sub_prog_node.end();
375349
376 const directory = self.base.emit.root_dir;350 const zcu_obj_path: ?Path = if (self.base.zcu_object_basename) |raw| p: {
377 const module_obj_path: ?Path = if (self.base.zcu_object_sub_path) |path| .{351 break :p try comp.resolveEmitPathFlush(arena, .temp, raw);
378 .root_dir = directory,
379 .sub_path = if (fs.path.dirname(self.base.emit.sub_path)) |dirname|
380 try fs.path.join(arena, &.{ dirname, path })
381 else
382 path,
383 } else null;352 } else null;
384353
385 // --verbose-link354 // --verbose-link
386 if (comp.verbose_link) try self.dumpArgv(comp);355 if (comp.verbose_link) try self.dumpArgv(comp);
387356
388 if (self.getZigObject()) |zo| try zo.flushModule(self, tid);357 if (self.getZigObject()) |zo| try zo.flush(self, tid);
389 if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path);358 if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, zcu_obj_path);
390 if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path);359 if (self.base.isObject()) return relocatable.flushObject(self, comp, zcu_obj_path);
391360
392 var positionals = std.ArrayList(link.Input).init(gpa);361 var positionals = std.ArrayList(link.Input).init(gpa);
393 defer positionals.deinit();362 defer positionals.deinit();
...@@ -409,7 +378,7 @@ pub fn flushModule(...@@ -409,7 +378,7 @@ pub fn flushModule(
409 positionals.appendAssumeCapacity(try link.openObjectInput(diags, key.status.success.object_path));378 positionals.appendAssumeCapacity(try link.openObjectInput(diags, key.status.success.object_path));
410 }379 }
411380
412 if (module_obj_path) |path| try positionals.append(try link.openObjectInput(diags, path));381 if (zcu_obj_path) |path| try positionals.append(try link.openObjectInput(diags, path));
413382
414 if (comp.config.any_sanitize_thread) {383 if (comp.config.any_sanitize_thread) {
415 try positionals.append(try link.openObjectInput(diags, comp.tsan_lib.?.full_object_path));384 try positionals.append(try link.openObjectInput(diags, comp.tsan_lib.?.full_object_path));
...@@ -629,7 +598,7 @@ pub fn flushModule(...@@ -629,7 +598,7 @@ pub fn flushModule(
629 error.LinkFailure => return error.LinkFailure,598 error.LinkFailure => return error.LinkFailure,
630 else => |e| return diags.fail("failed to calculate and write uuid: {s}", .{@errorName(e)}),599 else => |e| return diags.fail("failed to calculate and write uuid: {s}", .{@errorName(e)}),
631 };600 };
632 if (self.getDebugSymbols()) |dsym| dsym.flushModule(self) catch |err| switch (err) {601 if (self.getDebugSymbols()) |dsym| dsym.flush(self) catch |err| switch (err) {
633 error.OutOfMemory => return error.OutOfMemory,602 error.OutOfMemory => return error.OutOfMemory,
634 else => |e| return diags.fail("failed to get debug symbols: {s}", .{@errorName(e)}),603 else => |e| return diags.fail("failed to get debug symbols: {s}", .{@errorName(e)}),
635 };604 };
...@@ -658,12 +627,9 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {...@@ -658,12 +627,9 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {
658627
659 const directory = self.base.emit.root_dir;628 const directory = self.base.emit.root_dir;
660 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});629 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});
661 const module_obj_path: ?[]const u8 = if (self.base.zcu_object_sub_path) |path| blk: {630 const zcu_obj_path: ?[]const u8 = if (self.base.zcu_object_basename) |raw| p: {
662 if (fs.path.dirname(full_out_path)) |dirname| {631 const p = try comp.resolveEmitPathFlush(arena, .temp, raw);
663 break :blk try fs.path.join(arena, &.{ dirname, path });632 break :p try p.toString(arena);
664 } else {
665 break :blk path;
666 }
667 } else null;633 } else null;
668634
669 var argv = std.ArrayList([]const u8).init(arena);635 var argv = std.ArrayList([]const u8).init(arena);
...@@ -692,7 +658,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {...@@ -692,7 +658,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {
692 try argv.append(try key.status.success.object_path.toString(arena));658 try argv.append(try key.status.success.object_path.toString(arena));
693 }659 }
694660
695 if (module_obj_path) |p| {661 if (zcu_obj_path) |p| {
696 try argv.append(p);662 try argv.append(p);
697 }663 }
698 } else {664 } else {
...@@ -784,7 +750,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {...@@ -784,7 +750,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {
784 try argv.append(try key.status.success.object_path.toString(arena));750 try argv.append(try key.status.success.object_path.toString(arena));
785 }751 }
786752
787 if (module_obj_path) |p| {753 if (zcu_obj_path) |p| {
788 try argv.append(p);754 try argv.append(p);
789 }755 }
790756
...@@ -3073,26 +3039,22 @@ pub fn updateFunc(...@@ -3073,26 +3039,22 @@ pub fn updateFunc(
3073 self: *MachO,3039 self: *MachO,
3074 pt: Zcu.PerThread,3040 pt: Zcu.PerThread,
3075 func_index: InternPool.Index,3041 func_index: InternPool.Index,
3076 air: Air,3042 mir: *const codegen.AnyMir,
3077 liveness: Air.Liveness,
3078) link.File.UpdateNavError!void {3043) link.File.UpdateNavError!void {
3079 if (build_options.skip_non_native and builtin.object_format != .macho) {3044 if (build_options.skip_non_native and builtin.object_format != .macho) {
3080 @panic("Attempted to compile for object format that was disabled by build configuration");3045 @panic("Attempted to compile for object format that was disabled by build configuration");
3081 }3046 }
3082 if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(pt, func_index, air, liveness);3047 return self.getZigObject().?.updateFunc(self, pt, func_index, mir);
3083 return self.getZigObject().?.updateFunc(self, pt, func_index, air, liveness);
3084}3048}
30853049
3086pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {3050pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {
3087 if (build_options.skip_non_native and builtin.object_format != .macho) {3051 if (build_options.skip_non_native and builtin.object_format != .macho) {
3088 @panic("Attempted to compile for object format that was disabled by build configuration");3052 @panic("Attempted to compile for object format that was disabled by build configuration");
3089 }3053 }
3090 if (self.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav);
3091 return self.getZigObject().?.updateNav(self, pt, nav);3054 return self.getZigObject().?.updateNav(self, pt, nav);
3092}3055}
30933056
3094pub fn updateLineNumber(self: *MachO, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {3057pub fn updateLineNumber(self: *MachO, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
3095 if (self.llvm_object) |_| return;
3096 return self.getZigObject().?.updateLineNumber(pt, ti_id);3058 return self.getZigObject().?.updateLineNumber(pt, ti_id);
3097}3059}
30983060
...@@ -3105,7 +3067,6 @@ pub fn updateExports(...@@ -3105,7 +3067,6 @@ pub fn updateExports(
3105 if (build_options.skip_non_native and builtin.object_format != .macho) {3067 if (build_options.skip_non_native and builtin.object_format != .macho) {
3106 @panic("Attempted to compile for object format that was disabled by build configuration");3068 @panic("Attempted to compile for object format that was disabled by build configuration");
3107 }3069 }
3108 if (self.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices);
3109 return self.getZigObject().?.updateExports(self, pt, exported, export_indices);3070 return self.getZigObject().?.updateExports(self, pt, exported, export_indices);
3110}3071}
31113072
...@@ -3114,17 +3075,14 @@ pub fn deleteExport(...@@ -3114,17 +3075,14 @@ pub fn deleteExport(
3114 exported: Zcu.Exported,3075 exported: Zcu.Exported,
3115 name: InternPool.NullTerminatedString,3076 name: InternPool.NullTerminatedString,
3116) void {3077) void {
3117 if (self.llvm_object) |_| return;
3118 return self.getZigObject().?.deleteExport(self, exported, name);3078 return self.getZigObject().?.deleteExport(self, exported, name);
3119}3079}
31203080
3121pub fn freeNav(self: *MachO, nav: InternPool.Nav.Index) void {3081pub fn freeNav(self: *MachO, nav: InternPool.Nav.Index) void {
3122 if (self.llvm_object) |llvm_object| return llvm_object.freeNav(nav);
3123 return self.getZigObject().?.freeNav(nav);3082 return self.getZigObject().?.freeNav(nav);
3124}3083}
31253084
3126pub fn getNavVAddr(self: *MachO, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {3085pub fn getNavVAddr(self: *MachO, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {
3127 assert(self.llvm_object == null);
3128 return self.getZigObject().?.getNavVAddr(self, pt, nav_index, reloc_info);3086 return self.getZigObject().?.getNavVAddr(self, pt, nav_index, reloc_info);
3129}3087}
31303088
...@@ -3139,7 +3097,6 @@ pub fn lowerUav(...@@ -3139,7 +3097,6 @@ pub fn lowerUav(
3139}3097}
31403098
3141pub fn getUavVAddr(self: *MachO, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {3099pub fn getUavVAddr(self: *MachO, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
3142 assert(self.llvm_object == null);
3143 return self.getZigObject().?.getUavVAddr(self, uav, reloc_info);3100 return self.getZigObject().?.getUavVAddr(self, uav, reloc_info);
3144}3101}
31453102
...@@ -5473,7 +5430,6 @@ const target_util = @import("../target.zig");...@@ -5473,7 +5430,6 @@ const target_util = @import("../target.zig");
5473const trace = @import("../tracy.zig").trace;5430const trace = @import("../tracy.zig").trace;
5474const synthetic = @import("MachO/synthetic.zig");5431const synthetic = @import("MachO/synthetic.zig");
54755432
5476const Air = @import("../Air.zig");
5477const Alignment = Atom.Alignment;5433const Alignment = Atom.Alignment;
5478const Allocator = mem.Allocator;5434const Allocator = mem.Allocator;
5479const Archive = @import("MachO/Archive.zig");5435const Archive = @import("MachO/Archive.zig");
...@@ -5496,7 +5452,6 @@ const ObjcStubsSection = synthetic.ObjcStubsSection;...@@ -5496,7 +5452,6 @@ const ObjcStubsSection = synthetic.ObjcStubsSection;
5496const Object = @import("MachO/Object.zig");5452const Object = @import("MachO/Object.zig");
5497const LazyBind = bind.LazyBind;5453const LazyBind = bind.LazyBind;
5498const LaSymbolPtrSection = synthetic.LaSymbolPtrSection;5454const LaSymbolPtrSection = synthetic.LaSymbolPtrSection;
5499const LlvmObject = @import("../codegen/llvm.zig").Object;
5500const Md5 = std.crypto.hash.Md5;5455const Md5 = std.crypto.hash.Md5;
5501const Zcu = @import("../Zcu.zig");5456const Zcu = @import("../Zcu.zig");
5502const InternPool = @import("../InternPool.zig");5457const InternPool = @import("../InternPool.zig");
src/link/MachO/DebugSymbols.zig+1-1
...@@ -178,7 +178,7 @@ fn findFreeSpace(self: *DebugSymbols, object_size: u64, min_alignment: u64) !u64...@@ -178,7 +178,7 @@ fn findFreeSpace(self: *DebugSymbols, object_size: u64, min_alignment: u64) !u64
178 return offset;178 return offset;
179}179}
180180
181pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {181pub fn flush(self: *DebugSymbols, macho_file: *MachO) !void {
182 const zo = macho_file.getZigObject().?;182 const zo = macho_file.getZigObject().?;
183 for (self.relocs.items) |*reloc| {183 for (self.relocs.items) |*reloc| {
184 const sym = zo.symbols.items[reloc.target];184 const sym = zo.symbols.items[reloc.target];
src/link/MachO/Symbol.zig-3
...@@ -389,9 +389,6 @@ pub const Flags = packed struct {...@@ -389,9 +389,6 @@ pub const Flags = packed struct {
389 /// ZigObject specific flags389 /// ZigObject specific flags
390 /// Whether the symbol has a trampoline390 /// Whether the symbol has a trampoline
391 trampoline: bool = false,391 trampoline: bool = false,
392
393 /// Whether the symbol is an extern pointer (as opposed to function).
394 is_extern_ptr: bool = false,
395};392};
396393
397pub const SectionFlags = packed struct(u8) {394pub const SectionFlags = packed struct(u8) {
src/link/MachO/ZigObject.zig+9-17
...@@ -550,7 +550,7 @@ pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.se...@@ -550,7 +550,7 @@ pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.se
550 return sect;550 return sect;
551}551}
552552
553pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.File.FlushError!void {553pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.File.FlushError!void {
554 const diags = &macho_file.base.comp.link_diags;554 const diags = &macho_file.base.comp.link_diags;
555555
556 // Handle any lazy symbols that were emitted by incremental compilation.556 // Handle any lazy symbols that were emitted by incremental compilation.
...@@ -589,7 +589,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)...@@ -589,7 +589,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)
589 if (self.dwarf) |*dwarf| {589 if (self.dwarf) |*dwarf| {
590 const pt: Zcu.PerThread = .activate(macho_file.base.comp.zcu.?, tid);590 const pt: Zcu.PerThread = .activate(macho_file.base.comp.zcu.?, tid);
591 defer pt.deactivate();591 defer pt.deactivate();
592 dwarf.flushModule(pt) catch |err| switch (err) {592 dwarf.flush(pt) catch |err| switch (err) {
593 error.OutOfMemory => return error.OutOfMemory,593 error.OutOfMemory => return error.OutOfMemory,
594 else => |e| return diags.fail("failed to flush dwarf module: {s}", .{@errorName(e)}),594 else => |e| return diags.fail("failed to flush dwarf module: {s}", .{@errorName(e)}),
595 };595 };
...@@ -599,7 +599,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)...@@ -599,7 +599,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)
599 self.debug_strtab_dirty = false;599 self.debug_strtab_dirty = false;
600 }600 }
601601
602 // The point of flushModule() is to commit changes, so in theory, nothing should602 // The point of flush() is to commit changes, so in theory, nothing should
603 // be dirty after this. However, it is possible for some things to remain603 // be dirty after this. However, it is possible for some things to remain
604 // dirty because they fail to be written in the event of compile errors,604 // dirty because they fail to be written in the event of compile errors,
605 // such as debug_line_header_dirty and debug_info_header_dirty.605 // such as debug_line_header_dirty and debug_info_header_dirty.
...@@ -777,8 +777,7 @@ pub fn updateFunc(...@@ -777,8 +777,7 @@ pub fn updateFunc(
777 macho_file: *MachO,777 macho_file: *MachO,
778 pt: Zcu.PerThread,778 pt: Zcu.PerThread,
779 func_index: InternPool.Index,779 func_index: InternPool.Index,
780 air: Air,780 mir: *const codegen.AnyMir,
781 liveness: Air.Liveness,
782) link.File.UpdateNavError!void {781) link.File.UpdateNavError!void {
783 const tracy = trace(@src());782 const tracy = trace(@src());
784 defer tracy.end();783 defer tracy.end();
...@@ -796,13 +795,12 @@ pub fn updateFunc(...@@ -796,13 +795,12 @@ pub fn updateFunc(
796 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;795 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
797 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();796 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
798797
799 try codegen.generateFunction(798 try codegen.emitFunction(
800 &macho_file.base,799 &macho_file.base,
801 pt,800 pt,
802 zcu.navSrcLoc(func.owner_nav),801 zcu.navSrcLoc(func.owner_nav),
803 func_index,802 func_index,
804 air,803 mir,
805 liveness,
806 &code_buffer,804 &code_buffer,
807 if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,805 if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
808 );806 );
...@@ -883,11 +881,7 @@ pub fn updateNav(...@@ -883,11 +881,7 @@ pub fn updateNav(
883 const name = @"extern".name.toSlice(ip);881 const name = @"extern".name.toSlice(ip);
884 const lib_name = @"extern".lib_name.toSlice(ip);882 const lib_name = @"extern".lib_name.toSlice(ip);
885 const sym_index = try self.getGlobalSymbol(macho_file, name, lib_name);883 const sym_index = try self.getGlobalSymbol(macho_file, name, lib_name);
886 if (!ip.isFunctionType(@"extern".ty)) {884 if (@"extern".is_threadlocal and macho_file.base.comp.config.any_non_single_threaded) self.symbols.items[sym_index].flags.tlv = true;
887 const sym = &self.symbols.items[sym_index];
888 sym.flags.is_extern_ptr = true;
889 if (@"extern".is_threadlocal) sym.flags.tlv = true;
890 }
891 if (self.dwarf) |*dwarf| dwarf: {885 if (self.dwarf) |*dwarf| dwarf: {
892 var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf;886 var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf;
893 defer debug_wip_nav.deinit();887 defer debug_wip_nav.deinit();
...@@ -1160,7 +1154,6 @@ fn getNavOutputSection(...@@ -1160,7 +1154,6 @@ fn getNavOutputSection(
1160) error{OutOfMemory}!u8 {1154) error{OutOfMemory}!u8 {
1161 _ = self;1155 _ = self;
1162 const ip = &zcu.intern_pool;1156 const ip = &zcu.intern_pool;
1163 const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded;
1164 const nav_val = zcu.navValue(nav_index);1157 const nav_val = zcu.navValue(nav_index);
1165 if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) return macho_file.zig_text_sect_index.?;1158 if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) return macho_file.zig_text_sect_index.?;
1166 const is_const, const is_threadlocal, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {1159 const is_const, const is_threadlocal, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
...@@ -1168,7 +1161,7 @@ fn getNavOutputSection(...@@ -1168,7 +1161,7 @@ fn getNavOutputSection(
1168 .@"extern" => |@"extern"| .{ @"extern".is_const, @"extern".is_threadlocal, .none },1161 .@"extern" => |@"extern"| .{ @"extern".is_const, @"extern".is_threadlocal, .none },
1169 else => .{ true, false, nav_val.toIntern() },1162 else => .{ true, false, nav_val.toIntern() },
1170 };1163 };
1171 if (any_non_single_threaded and is_threadlocal) {1164 if (is_threadlocal and macho_file.base.comp.config.any_non_single_threaded) {
1172 for (code) |byte| {1165 for (code) |byte| {
1173 if (byte != 0) break;1166 if (byte != 0) break;
1174 } else return macho_file.getSectionByName("__DATA", "__thread_bss") orelse try macho_file.addSection(1167 } else return macho_file.getSectionByName("__DATA", "__thread_bss") orelse try macho_file.addSection(
...@@ -1537,7 +1530,7 @@ pub fn getOrCreateMetadataForLazySymbol(...@@ -1537,7 +1530,7 @@ pub fn getOrCreateMetadataForLazySymbol(
1537 }1530 }
1538 state_ptr.* = .pending_flush;1531 state_ptr.* = .pending_flush;
1539 const symbol_index = symbol_index_ptr.*;1532 const symbol_index = symbol_index_ptr.*;
1540 // anyerror needs to be deferred until flushModule1533 // anyerror needs to be deferred until flush
1541 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbol(macho_file, pt, lazy_sym, symbol_index);1534 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbol(macho_file, pt, lazy_sym, symbol_index);
1542 return symbol_index;1535 return symbol_index;
1543}1536}
...@@ -1813,7 +1806,6 @@ const target_util = @import("../../target.zig");...@@ -1813,7 +1806,6 @@ const target_util = @import("../../target.zig");
1813const trace = @import("../../tracy.zig").trace;1806const trace = @import("../../tracy.zig").trace;
1814const std = @import("std");1807const std = @import("std");
18151808
1816const Air = @import("../../Air.zig");
1817const Allocator = std.mem.Allocator;1809const Allocator = std.mem.Allocator;
1818const Archive = @import("Archive.zig");1810const Archive = @import("Archive.zig");
1819const Atom = @import("Atom.zig");1811const Atom = @import("Atom.zig");
src/link/Plan9.zig+14-34
...@@ -301,7 +301,6 @@ pub fn createEmpty(...@@ -301,7 +301,6 @@ pub fn createEmpty(
301 .stack_size = options.stack_size orelse 16777216,301 .stack_size = options.stack_size orelse 16777216,
302 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,302 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
303 .file = null,303 .file = null,
304 .disable_lld_caching = options.disable_lld_caching,
305 .build_id = options.build_id,304 .build_id = options.build_id,
306 },305 },
307 .sixtyfour_bit = sixtyfour_bit,306 .sixtyfour_bit = sixtyfour_bit,
...@@ -387,8 +386,7 @@ pub fn updateFunc(...@@ -387,8 +386,7 @@ pub fn updateFunc(
387 self: *Plan9,386 self: *Plan9,
388 pt: Zcu.PerThread,387 pt: Zcu.PerThread,
389 func_index: InternPool.Index,388 func_index: InternPool.Index,
390 air: Air,389 mir: *const codegen.AnyMir,
391 liveness: Air.Liveness,
392) link.File.UpdateNavError!void {390) link.File.UpdateNavError!void {
393 if (build_options.skip_non_native and builtin.object_format != .plan9) {391 if (build_options.skip_non_native and builtin.object_format != .plan9) {
394 @panic("Attempted to compile for object format that was disabled by build configuration");392 @panic("Attempted to compile for object format that was disabled by build configuration");
...@@ -413,13 +411,12 @@ pub fn updateFunc(...@@ -413,13 +411,12 @@ pub fn updateFunc(
413 };411 };
414 defer dbg_info_output.dbg_line.deinit();412 defer dbg_info_output.dbg_line.deinit();
415413
416 try codegen.generateFunction(414 try codegen.emitFunction(
417 &self.base,415 &self.base,
418 pt,416 pt,
419 zcu.navSrcLoc(func.owner_nav),417 zcu.navSrcLoc(func.owner_nav),
420 func_index,418 func_index,
421 air,419 mir,
422 liveness,
423 &code_buffer,420 &code_buffer,
424 .{ .plan9 = &dbg_info_output },421 .{ .plan9 = &dbg_info_output },
425 );422 );
...@@ -494,7 +491,7 @@ fn updateFinish(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index...@@ -494,7 +491,7 @@ fn updateFinish(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index
494 // write the symbol491 // write the symbol
495 // we already have the got index492 // we already have the got index
496 const sym: aout.Sym = .{493 const sym: aout.Sym = .{
497 .value = undefined, // the value of stuff gets filled in in flushModule494 .value = undefined, // the value of stuff gets filled in in flush
498 .type = atom.type,495 .type = atom.type,
499 .name = try gpa.dupe(u8, nav.name.toSlice(ip)),496 .name = try gpa.dupe(u8, nav.name.toSlice(ip)),
500 };497 };
...@@ -527,25 +524,6 @@ fn allocateGotIndex(self: *Plan9) usize {...@@ -527,25 +524,6 @@ fn allocateGotIndex(self: *Plan9) usize {
527 }524 }
528}525}
529526
530pub fn flush(
531 self: *Plan9,
532 arena: Allocator,
533 tid: Zcu.PerThread.Id,
534 prog_node: std.Progress.Node,
535) link.File.FlushError!void {
536 const comp = self.base.comp;
537 const diags = &comp.link_diags;
538 const use_lld = build_options.have_llvm and comp.config.use_lld;
539 assert(!use_lld);
540
541 switch (link.File.effectiveOutputMode(use_lld, comp.config.output_mode)) {
542 .Exe => {},
543 .Obj => return diags.fail("writing plan9 object files unimplemented", .{}),
544 .Lib => return diags.fail("writing plan9 lib files unimplemented", .{}),
545 }
546 return self.flushModule(arena, tid, prog_node);
547}
548
549pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void {527pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void {
550 if (delta_line > 0 and delta_line < 65) {528 if (delta_line > 0 and delta_line < 65) {
551 const toappend = @as(u8, @intCast(delta_line));529 const toappend = @as(u8, @intCast(delta_line));
...@@ -586,7 +564,7 @@ fn atomCount(self: *Plan9) usize {...@@ -586,7 +564,7 @@ fn atomCount(self: *Plan9) usize {
586 return data_nav_count + fn_nav_count + lazy_atom_count + extern_atom_count + uav_atom_count;564 return data_nav_count + fn_nav_count + lazy_atom_count + extern_atom_count + uav_atom_count;
587}565}
588566
589pub fn flushModule(567pub fn flush(
590 self: *Plan9,568 self: *Plan9,
591 arena: Allocator,569 arena: Allocator,
592 /// TODO: stop using this570 /// TODO: stop using this
...@@ -607,10 +585,16 @@ pub fn flushModule(...@@ -607,10 +585,16 @@ pub fn flushModule(
607 const gpa = comp.gpa;585 const gpa = comp.gpa;
608 const target = comp.root_mod.resolved_target.result;586 const target = comp.root_mod.resolved_target.result;
609587
588 switch (comp.config.output_mode) {
589 .Exe => {},
590 .Obj => return diags.fail("writing plan9 object files unimplemented", .{}),
591 .Lib => return diags.fail("writing plan9 lib files unimplemented", .{}),
592 }
593
610 const sub_prog_node = prog_node.start("Flush Module", 0);594 const sub_prog_node = prog_node.start("Flush Module", 0);
611 defer sub_prog_node.end();595 defer sub_prog_node.end();
612596
613 log.debug("flushModule", .{});597 log.debug("flush", .{});
614598
615 defer assert(self.hdr.entry != 0x0);599 defer assert(self.hdr.entry != 0x0);
616600
...@@ -1039,7 +1023,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *Plan9, pt: Zcu.PerThread, lazy_sym: F...@@ -1039,7 +1023,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *Plan9, pt: Zcu.PerThread, lazy_sym: F
1039 const atom = atom_ptr.*;1023 const atom = atom_ptr.*;
1040 _ = try self.getAtomPtr(atom).getOrCreateSymbolTableEntry(self);1024 _ = try self.getAtomPtr(atom).getOrCreateSymbolTableEntry(self);
1041 _ = self.getAtomPtr(atom).getOrCreateOffsetTableEntry(self);1025 _ = self.getAtomPtr(atom).getOrCreateOffsetTableEntry(self);
1042 // anyerror needs to be deferred until flushModule1026 // anyerror needs to be deferred until flush
1043 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbolAtom(pt, lazy_sym, atom);1027 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbolAtom(pt, lazy_sym, atom);
1044 return atom;1028 return atom;
1045}1029}
...@@ -1182,11 +1166,7 @@ pub fn open(...@@ -1182,11 +1166,7 @@ pub fn open(
11821166
1183 const file = try emit.root_dir.handle.createFile(emit.sub_path, .{1167 const file = try emit.root_dir.handle.createFile(emit.sub_path, .{
1184 .read = true,1168 .read = true,
1185 .mode = link.File.determineMode(1169 .mode = link.File.determineMode(comp.config.output_mode, comp.config.link_mode),
1186 use_lld,
1187 comp.config.output_mode,
1188 comp.config.link_mode,
1189 ),
1190 });1170 });
1191 errdefer file.close();1171 errdefer file.close();
1192 self.base.file = file;1172 self.base.file = file;
src/link/Queue.zig created+279
...@@ -0,0 +1,279 @@
1//! Stores and manages the queue of link tasks. Each task is either a `PrelinkTask` or a `ZcuTask`.
2//!
3//! There must be at most one link thread (the thread processing these tasks) active at a time. If
4//! `!comp.separateCodegenThreadOk()`, then ZCU tasks will be run on the main thread, bypassing this
5//! queue entirely.
6//!
7//! All prelink tasks must be processed before any ZCU tasks are processed. After all prelink tasks
8//! are run, but before any ZCU tasks are run, `prelink` must be called on the `link.File`.
9//!
10//! There will sometimes be a `ZcuTask` in the queue which is not yet ready because it depends on
11//! MIR which has not yet been generated by any codegen thread. In this case, we must pause
12//! processing of linker tasks until the MIR is ready. It would be incorrect to run any other link
13//! tasks first, since this would make builds unreproducible.
14
15mutex: std.Thread.Mutex,
16/// Validates that only one `flushTaskQueue` thread is running at a time.
17flush_safety: std.debug.SafetyLock,
18
19/// This is the number of prelink tasks which are expected but have not yet been enqueued.
20/// Guarded by `mutex`.
21pending_prelink_tasks: u32,
22
23/// Prelink tasks which have been enqueued and are not yet owned by the worker thread.
24/// Allocated into `gpa`, guarded by `mutex`.
25queued_prelink: std.ArrayListUnmanaged(PrelinkTask),
26/// The worker thread moves items from `queued_prelink` into this array in order to process them.
27/// Allocated into `gpa`, accessed only by the worker thread.
28wip_prelink: std.ArrayListUnmanaged(PrelinkTask),
29
30/// Like `queued_prelink`, but for ZCU tasks.
31/// Allocated into `gpa`, guarded by `mutex`.
32queued_zcu: std.ArrayListUnmanaged(ZcuTask),
33/// Like `wip_prelink`, but for ZCU tasks.
34/// Allocated into `gpa`, accessed only by the worker thread.
35wip_zcu: std.ArrayListUnmanaged(ZcuTask),
36
37/// When processing ZCU link tasks, we might have to block due to unpopulated MIR. When this
38/// happens, some tasks in `wip_zcu` have been run, and some are still pending. This is the
39/// index into `wip_zcu` which we have reached.
40wip_zcu_idx: usize,
41
42/// The sum of all `air_bytes` for all currently-queued `ZcuTask.link_func` tasks. Because
43/// MIR bytes are approximately proportional to AIR bytes, this acts to limit the amount of
44/// AIR and MIR which is queued for codegen and link respectively, to prevent excessive
45/// memory usage if analysis produces AIR faster than it can be processed by codegen/link.
46/// The cap is `max_air_bytes_in_flight`.
47/// Guarded by `mutex`.
48air_bytes_in_flight: u32,
49/// If nonzero, then a call to `enqueueZcu` is blocked waiting to add a `link_func` task, but
50/// cannot until `air_bytes_in_flight` is no greater than this value.
51/// Guarded by `mutex`.
52air_bytes_waiting: u32,
53/// After setting `air_bytes_waiting`, `enqueueZcu` will wait on this condition (with `mutex`).
54/// When `air_bytes_waiting` many bytes can be queued, this condition should be signaled.
55air_bytes_cond: std.Thread.Condition,
56
57/// Guarded by `mutex`.
58state: union(enum) {
59 /// The link thread is currently running or queued to run.
60 running,
61 /// The link thread is not running or queued, because it has exhausted all immediately available
62 /// tasks. It should be spawned when more tasks are enqueued. If `pending_prelink_tasks` is not
63 /// zero, we are specifically waiting for prelink tasks.
64 finished,
65 /// The link thread is not running or queued, because it is waiting for this MIR to be populated.
66 /// Once codegen completes, it must call `mirReady` which will restart the link thread.
67 wait_for_mir: *ZcuTask.LinkFunc.SharedMir,
68},
69
70/// In the worst observed case, MIR is around 50 times as large as AIR. More typically, the ratio is
71/// around 20. Going by that 50x multiplier, and assuming we want to consume no more than 500 MiB of
72/// memory on AIR/MIR, we see a limit of around 10 MiB of AIR in-flight.
73const max_air_bytes_in_flight = 10 * 1024 * 1024;
74
75/// The initial `Queue` state, containing no tasks, expecting no prelink tasks, and with no running worker thread.
76/// The `pending_prelink_tasks` and `queued_prelink` fields may be modified as needed before calling `start`.
77pub const empty: Queue = .{
78 .mutex = .{},
79 .flush_safety = .{},
80 .pending_prelink_tasks = 0,
81 .queued_prelink = .empty,
82 .wip_prelink = .empty,
83 .queued_zcu = .empty,
84 .wip_zcu = .empty,
85 .wip_zcu_idx = 0,
86 .state = .finished,
87 .air_bytes_in_flight = 0,
88 .air_bytes_waiting = 0,
89 .air_bytes_cond = .{},
90};
91/// `lf` is needed to correctly deinit any pending `ZcuTask`s.
92pub fn deinit(q: *Queue, comp: *Compilation) void {
93 const gpa = comp.gpa;
94 for (q.queued_zcu.items) |t| t.deinit(comp.zcu.?);
95 for (q.wip_zcu.items[q.wip_zcu_idx..]) |t| t.deinit(comp.zcu.?);
96 q.queued_prelink.deinit(gpa);
97 q.wip_prelink.deinit(gpa);
98 q.queued_zcu.deinit(gpa);
99 q.wip_zcu.deinit(gpa);
100}
101
102/// This is expected to be called exactly once, after which the caller must not directly access
103/// `queued_prelink` or `pending_prelink_tasks` any longer. This will spawn the link thread if
104/// necessary.
105pub fn start(q: *Queue, comp: *Compilation) void {
106 assert(q.state == .finished);
107 assert(q.queued_zcu.items.len == 0);
108 if (q.queued_prelink.items.len != 0) {
109 q.state = .running;
110 comp.thread_pool.spawnWgId(&comp.link_task_wait_group, flushTaskQueue, .{ q, comp });
111 }
112}
113
114/// Called by codegen workers after they have populated a `ZcuTask.LinkFunc.SharedMir`. If the link
115/// thread was waiting for this MIR, it can resume.
116pub fn mirReady(q: *Queue, comp: *Compilation, mir: *ZcuTask.LinkFunc.SharedMir) void {
117 // We would like to assert that `mir` is not pending, but that would race with a worker thread
118 // potentially freeing it.
119 {
120 q.mutex.lock();
121 defer q.mutex.unlock();
122 switch (q.state) {
123 .finished, .running => return,
124 .wait_for_mir => |wait_for| if (wait_for != mir) return,
125 }
126 // We were waiting for `mir`, so we will restart the linker thread.
127 q.state = .running;
128 }
129 assert(mir.status.load(.monotonic) != .pending);
130 comp.thread_pool.spawnWgId(&comp.link_task_wait_group, flushTaskQueue, .{ q, comp });
131}
132
133/// Enqueues all prelink tasks in `tasks`. Asserts that they were expected, i.e. that `tasks.len` is
134/// less than or equal to `q.pending_prelink_tasks`. Also asserts that `tasks.len` is not 0.
135pub fn enqueuePrelink(q: *Queue, comp: *Compilation, tasks: []const PrelinkTask) Allocator.Error!void {
136 {
137 q.mutex.lock();
138 defer q.mutex.unlock();
139 try q.queued_prelink.appendSlice(comp.gpa, tasks);
140 q.pending_prelink_tasks -= @intCast(tasks.len);
141 switch (q.state) {
142 .wait_for_mir => unreachable, // we've not started zcu tasks yet
143 .running => return,
144 .finished => {},
145 }
146 // Restart the linker thread, because it was waiting for a task
147 q.state = .running;
148 }
149 comp.thread_pool.spawnWgId(&comp.link_task_wait_group, flushTaskQueue, .{ q, comp });
150}
151
152pub fn enqueueZcu(q: *Queue, comp: *Compilation, task: ZcuTask) Allocator.Error!void {
153 assert(comp.separateCodegenThreadOk());
154 {
155 q.mutex.lock();
156 defer q.mutex.unlock();
157 // If this is a `link_func` task, we might need to wait for `air_bytes_in_flight` to fall.
158 if (task == .link_func) {
159 const max_in_flight = max_air_bytes_in_flight -| task.link_func.air_bytes;
160 while (q.air_bytes_in_flight > max_in_flight) {
161 q.air_bytes_waiting = task.link_func.air_bytes;
162 q.air_bytes_cond.wait(&q.mutex);
163 q.air_bytes_waiting = 0;
164 }
165 q.air_bytes_in_flight += task.link_func.air_bytes;
166 }
167 try q.queued_zcu.append(comp.gpa, task);
168 switch (q.state) {
169 .running, .wait_for_mir => return,
170 .finished => if (q.pending_prelink_tasks != 0) return,
171 }
172 // Restart the linker thread, unless it would immediately be blocked
173 if (task == .link_func and task.link_func.mir.status.load(.monotonic) == .pending) {
174 q.state = .{ .wait_for_mir = task.link_func.mir };
175 return;
176 }
177 q.state = .running;
178 }
179 comp.thread_pool.spawnWgId(&comp.link_task_wait_group, flushTaskQueue, .{ q, comp });
180}
181
182fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void {
183 q.flush_safety.lock(); // every `return` site should unlock this before unlocking `q.mutex`
184
185 if (std.debug.runtime_safety) {
186 q.mutex.lock();
187 defer q.mutex.unlock();
188 assert(q.state == .running);
189 }
190 prelink: while (true) {
191 assert(q.wip_prelink.items.len == 0);
192 {
193 q.mutex.lock();
194 defer q.mutex.unlock();
195 std.mem.swap(std.ArrayListUnmanaged(PrelinkTask), &q.queued_prelink, &q.wip_prelink);
196 if (q.wip_prelink.items.len == 0) {
197 if (q.pending_prelink_tasks == 0) {
198 break :prelink; // prelink is done
199 } else {
200 // We're expecting more prelink tasks so can't move on to ZCU tasks.
201 q.state = .finished;
202 q.flush_safety.unlock();
203 return;
204 }
205 }
206 }
207 for (q.wip_prelink.items) |task| {
208 link.doPrelinkTask(comp, task);
209 }
210 q.wip_prelink.clearRetainingCapacity();
211 }
212
213 // We've finished the prelink tasks, so run prelink if necessary.
214 if (comp.bin_file) |lf| {
215 if (!lf.post_prelink) {
216 if (lf.prelink()) |_| {
217 lf.post_prelink = true;
218 } else |err| switch (err) {
219 error.OutOfMemory => comp.link_diags.setAllocFailure(),
220 error.LinkFailure => {},
221 }
222 }
223 }
224
225 // Now we can run ZCU tasks.
226 while (true) {
227 if (q.wip_zcu.items.len == q.wip_zcu_idx) {
228 q.wip_zcu.clearRetainingCapacity();
229 q.wip_zcu_idx = 0;
230 q.mutex.lock();
231 defer q.mutex.unlock();
232 std.mem.swap(std.ArrayListUnmanaged(ZcuTask), &q.queued_zcu, &q.wip_zcu);
233 if (q.wip_zcu.items.len == 0) {
234 // We've exhausted all available tasks.
235 q.state = .finished;
236 q.flush_safety.unlock();
237 return;
238 }
239 }
240 const task = q.wip_zcu.items[q.wip_zcu_idx];
241 // If the task is a `link_func`, we might have to stop until its MIR is populated.
242 pending: {
243 if (task != .link_func) break :pending;
244 const status_ptr = &task.link_func.mir.status;
245 // First check without the mutex to optimize for the common case where MIR is ready.
246 if (status_ptr.load(.monotonic) != .pending) break :pending;
247 q.mutex.lock();
248 defer q.mutex.unlock();
249 if (status_ptr.load(.monotonic) != .pending) break :pending;
250 // We will stop for now, and get restarted once this MIR is ready.
251 q.state = .{ .wait_for_mir = task.link_func.mir };
252 q.flush_safety.unlock();
253 return;
254 }
255 link.doZcuTask(comp, tid, task);
256 task.deinit(comp.zcu.?);
257 if (task == .link_func) {
258 // Decrease `air_bytes_in_flight`, since we've finished processing this MIR.
259 q.mutex.lock();
260 defer q.mutex.unlock();
261 q.air_bytes_in_flight -= task.link_func.air_bytes;
262 if (q.air_bytes_waiting != 0 and
263 q.air_bytes_in_flight <= max_air_bytes_in_flight -| q.air_bytes_waiting)
264 {
265 q.air_bytes_cond.signal();
266 }
267 }
268 q.wip_zcu_idx += 1;
269 }
270}
271
272const std = @import("std");
273const assert = std.debug.assert;
274const Allocator = std.mem.Allocator;
275const Compilation = @import("../Compilation.zig");
276const link = @import("../link.zig");
277const PrelinkTask = link.PrelinkTask;
278const ZcuTask = link.ZcuTask;
279const Queue = @This();
src/link/SpirV.zig+3-26
...@@ -17,7 +17,7 @@...@@ -17,7 +17,7 @@
17//! All regular functions.17//! All regular functions.
1818
19// Because SPIR-V requires re-compilation anyway, and so hot swapping will not work19// Because SPIR-V requires re-compilation anyway, and so hot swapping will not work
20// anyway, we simply generate all the code in flushModule. This keeps20// anyway, we simply generate all the code in flush. This keeps
21// things considerably simpler.21// things considerably simpler.
2222
23const SpirV = @This();23const SpirV = @This();
...@@ -83,7 +83,6 @@ pub fn createEmpty(...@@ -83,7 +83,6 @@ pub fn createEmpty(
83 .stack_size = options.stack_size orelse 0,83 .stack_size = options.stack_size orelse 0,
84 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,84 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
85 .file = null,85 .file = null,
86 .disable_lld_caching = options.disable_lld_caching,
87 .build_id = options.build_id,86 .build_id = options.build_id,
88 },87 },
89 .object = codegen.Object.init(gpa, comp.getTarget()),88 .object = codegen.Object.init(gpa, comp.getTarget()),
...@@ -112,24 +111,6 @@ pub fn deinit(self: *SpirV) void {...@@ -112,24 +111,6 @@ pub fn deinit(self: *SpirV) void {
112 self.object.deinit();111 self.object.deinit();
113}112}
114113
115pub fn updateFunc(
116 self: *SpirV,
117 pt: Zcu.PerThread,
118 func_index: InternPool.Index,
119 air: Air,
120 liveness: Air.Liveness,
121) link.File.UpdateNavError!void {
122 if (build_options.skip_non_native) {
123 @panic("Attempted to compile for architecture that was disabled by build configuration");
124 }
125
126 const ip = &pt.zcu.intern_pool;
127 const func = pt.zcu.funcInfo(func_index);
128 log.debug("lowering function {}", .{ip.getNav(func.owner_nav).name.fmt(ip)});
129
130 try self.object.updateFunc(pt, func_index, air, liveness);
131}
132
133pub fn updateNav(self: *SpirV, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {114pub fn updateNav(self: *SpirV, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {
134 if (build_options.skip_non_native) {115 if (build_options.skip_non_native) {
135 @panic("Attempted to compile for architecture that was disabled by build configuration");116 @panic("Attempted to compile for architecture that was disabled by build configuration");
...@@ -193,18 +174,14 @@ pub fn updateExports(...@@ -193,18 +174,14 @@ pub fn updateExports(
193 // TODO: Export regular functions, variables, etc using Linkage attributes.174 // TODO: Export regular functions, variables, etc using Linkage attributes.
194}175}
195176
196pub fn flush(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {177pub fn flush(
197 return self.flushModule(arena, tid, prog_node);
198}
199
200pub fn flushModule(
201 self: *SpirV,178 self: *SpirV,
202 arena: Allocator,179 arena: Allocator,
203 tid: Zcu.PerThread.Id,180 tid: Zcu.PerThread.Id,
204 prog_node: std.Progress.Node,181 prog_node: std.Progress.Node,
205) link.File.FlushError!void {182) link.File.FlushError!void {
206 // The goal is to never use this because it's only needed if we need to183 // The goal is to never use this because it's only needed if we need to
207 // write to InternPool, but flushModule is too late to be writing to the184 // write to InternPool, but flush is too late to be writing to the
208 // InternPool.185 // InternPool.
209 _ = tid;186 _ = tid;
210187
src/link/Wasm.zig+143-559
...@@ -29,19 +29,16 @@ const leb = std.leb;...@@ -29,19 +29,16 @@ const leb = std.leb;
29const log = std.log.scoped(.link);29const log = std.log.scoped(.link);
30const mem = std.mem;30const mem = std.mem;
3131
32const Air = @import("../Air.zig");
33const Mir = @import("../arch/wasm/Mir.zig");32const Mir = @import("../arch/wasm/Mir.zig");
34const CodeGen = @import("../arch/wasm/CodeGen.zig");33const CodeGen = @import("../arch/wasm/CodeGen.zig");
35const abi = @import("../arch/wasm/abi.zig");34const abi = @import("../arch/wasm/abi.zig");
36const Compilation = @import("../Compilation.zig");35const Compilation = @import("../Compilation.zig");
37const Dwarf = @import("Dwarf.zig");36const Dwarf = @import("Dwarf.zig");
38const InternPool = @import("../InternPool.zig");37const InternPool = @import("../InternPool.zig");
39const LlvmObject = @import("../codegen/llvm.zig").Object;
40const Zcu = @import("../Zcu.zig");38const Zcu = @import("../Zcu.zig");
41const codegen = @import("../codegen.zig");39const codegen = @import("../codegen.zig");
42const dev = @import("../dev.zig");40const dev = @import("../dev.zig");
43const link = @import("../link.zig");41const link = @import("../link.zig");
44const lldMain = @import("../main.zig").lldMain;
45const trace = @import("../tracy.zig").trace;42const trace = @import("../tracy.zig").trace;
46const wasi_libc = @import("../libs/wasi_libc.zig");43const wasi_libc = @import("../libs/wasi_libc.zig");
47const Value = @import("../Value.zig");44const Value = @import("../Value.zig");
...@@ -75,14 +72,10 @@ global_base: ?u64,...@@ -75,14 +72,10 @@ global_base: ?u64,
75initial_memory: ?u64,72initial_memory: ?u64,
76/// When defined, sets the maximum memory size of the memory.73/// When defined, sets the maximum memory size of the memory.
77max_memory: ?u64,74max_memory: ?u64,
78/// When true, will import the function table from the host environment.
79import_table: bool,
80/// When true, will export the function table to the host environment.75/// When true, will export the function table to the host environment.
81export_table: bool,76export_table: bool,
82/// Output name of the file77/// Output name of the file
83name: []const u8,78name: []const u8,
84/// If this is not null, an object file is created by LLVM and linked with LLD afterwards.
85llvm_object: ?LlvmObject.Ptr = null,
86/// List of relocatable files to be linked into the final binary.79/// List of relocatable files to be linked into the final binary.
87objects: std.ArrayListUnmanaged(Object) = .{},80objects: std.ArrayListUnmanaged(Object) = .{},
8881
...@@ -288,7 +281,7 @@ mir_instructions: std.MultiArrayList(Mir.Inst) = .{},...@@ -288,7 +281,7 @@ mir_instructions: std.MultiArrayList(Mir.Inst) = .{},
288/// Corresponds to `mir_instructions`.281/// Corresponds to `mir_instructions`.
289mir_extra: std.ArrayListUnmanaged(u32) = .empty,282mir_extra: std.ArrayListUnmanaged(u32) = .empty,
290/// All local types for all Zcu functions.283/// All local types for all Zcu functions.
291all_zcu_locals: std.ArrayListUnmanaged(std.wasm.Valtype) = .empty,284mir_locals: std.ArrayListUnmanaged(std.wasm.Valtype) = .empty,
292285
293params_scratch: std.ArrayListUnmanaged(std.wasm.Valtype) = .empty,286params_scratch: std.ArrayListUnmanaged(std.wasm.Valtype) = .empty,
294returns_scratch: std.ArrayListUnmanaged(std.wasm.Valtype) = .empty,287returns_scratch: std.ArrayListUnmanaged(std.wasm.Valtype) = .empty,
...@@ -872,9 +865,24 @@ const ZcuDataStarts = struct {...@@ -872,9 +865,24 @@ const ZcuDataStarts = struct {
872};865};
873866
874pub const ZcuFunc = union {867pub const ZcuFunc = union {
875 function: CodeGen.Function,868 function: Function,
876 tag_name: TagName,869 tag_name: TagName,
877870
871 pub const Function = extern struct {
872 /// Index into `Wasm.mir_instructions`.
873 instructions_off: u32,
874 /// This is unused except for as a safety slice bound and could be removed.
875 instructions_len: u32,
876 /// Index into `Wasm.mir_extra`.
877 extra_off: u32,
878 /// This is unused except for as a safety slice bound and could be removed.
879 extra_len: u32,
880 /// Index into `Wasm.mir_locals`.
881 locals_off: u32,
882 locals_len: u32,
883 prologue: Mir.Prologue,
884 };
885
878 pub const TagName = extern struct {886 pub const TagName = extern struct {
879 symbol_name: String,887 symbol_name: String,
880 type_index: FunctionType.Index,888 type_index: FunctionType.Index,
...@@ -2938,28 +2946,20 @@ pub fn createEmpty(...@@ -2938,28 +2946,20 @@ pub fn createEmpty(
2938 const target = comp.root_mod.resolved_target.result;2946 const target = comp.root_mod.resolved_target.result;
2939 assert(target.ofmt == .wasm);2947 assert(target.ofmt == .wasm);
29402948
2941 const use_lld = build_options.have_llvm and comp.config.use_lld;
2942 const use_llvm = comp.config.use_llvm;2949 const use_llvm = comp.config.use_llvm;
2943 const output_mode = comp.config.output_mode;2950 const output_mode = comp.config.output_mode;
2944 const wasi_exec_model = comp.config.wasi_exec_model;2951 const wasi_exec_model = comp.config.wasi_exec_model;
29452952
2946 // If using LLD to link, this code should produce an object file so that it
2947 // can be passed to LLD.
2948 // If using LLVM to generate the object file for the zig compilation unit,
2949 // we need a place to put the object file so that it can be subsequently
2950 // handled.
2951 const zcu_object_sub_path = if (!use_lld and !use_llvm)
2952 null
2953 else
2954 try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path});
2955
2956 const wasm = try arena.create(Wasm);2953 const wasm = try arena.create(Wasm);
2957 wasm.* = .{2954 wasm.* = .{
2958 .base = .{2955 .base = .{
2959 .tag = .wasm,2956 .tag = .wasm,
2960 .comp = comp,2957 .comp = comp,
2961 .emit = emit,2958 .emit = emit,
2962 .zcu_object_sub_path = zcu_object_sub_path,2959 .zcu_object_basename = if (use_llvm)
2960 try std.fmt.allocPrint(arena, "{s}_zcu.o", .{fs.path.stem(emit.sub_path)})
2961 else
2962 null,
2963 // Garbage collection is so crucial to WebAssembly that we design2963 // Garbage collection is so crucial to WebAssembly that we design
2964 // the linker around the assumption that it will be on in the vast2964 // the linker around the assumption that it will be on in the vast
2965 // majority of cases, and therefore express "no garbage collection"2965 // majority of cases, and therefore express "no garbage collection"
...@@ -2973,13 +2973,11 @@ pub fn createEmpty(...@@ -2973,13 +2973,11 @@ pub fn createEmpty(
2973 },2973 },
2974 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,2974 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
2975 .file = null,2975 .file = null,
2976 .disable_lld_caching = options.disable_lld_caching,
2977 .build_id = options.build_id,2976 .build_id = options.build_id,
2978 },2977 },
2979 .name = undefined,2978 .name = undefined,
2980 .string_table = .empty,2979 .string_table = .empty,
2981 .string_bytes = .empty,2980 .string_bytes = .empty,
2982 .import_table = options.import_table,
2983 .export_table = options.export_table,2981 .export_table = options.export_table,
2984 .import_symbols = options.import_symbols,2982 .import_symbols = options.import_symbols,
2985 .export_symbol_names = options.export_symbol_names,2983 .export_symbol_names = options.export_symbol_names,
...@@ -2992,9 +2990,6 @@ pub fn createEmpty(...@@ -2992,9 +2990,6 @@ pub fn createEmpty(
2992 .object_host_name = .none,2990 .object_host_name = .none,
2993 .preloaded_strings = undefined,2991 .preloaded_strings = undefined,
2994 };2992 };
2995 if (use_llvm and comp.config.have_zcu) {
2996 wasm.llvm_object = try LlvmObject.create(arena, comp);
2997 }
2998 errdefer wasm.base.destroy();2993 errdefer wasm.base.destroy();
29992994
3000 if (options.object_host_name) |name| wasm.object_host_name = (try wasm.internString(name)).toOptional();2995 if (options.object_host_name) |name| wasm.object_host_name = (try wasm.internString(name)).toOptional();
...@@ -3010,17 +3005,7 @@ pub fn createEmpty(...@@ -3010,17 +3005,7 @@ pub fn createEmpty(
3010 .named => |name| (try wasm.internString(name)).toOptional(),3005 .named => |name| (try wasm.internString(name)).toOptional(),
3011 };3006 };
30123007
3013 if (use_lld and (use_llvm or !comp.config.have_zcu)) {3008 wasm.base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{
3014 // LLVM emits the object file (if any); LLD links it into the final product.
3015 return wasm;
3016 }
3017
3018 // What path should this Wasm linker code output to?
3019 // If using LLD to link, this code should produce an object file so that it
3020 // can be passed to LLD.
3021 const sub_path = if (use_lld) zcu_object_sub_path.? else emit.sub_path;
3022
3023 wasm.base.file = try emit.root_dir.handle.createFile(sub_path, .{
3024 .truncate = true,3009 .truncate = true,
3025 .read = true,3010 .read = true,
3026 .mode = if (fs.has_executable_bit)3011 .mode = if (fs.has_executable_bit)
...@@ -3031,7 +3016,7 @@ pub fn createEmpty(...@@ -3031,7 +3016,7 @@ pub fn createEmpty(
3031 else3016 else
3032 0,3017 0,
3033 });3018 });
3034 wasm.name = sub_path;3019 wasm.name = emit.sub_path;
30353020
3036 return wasm;3021 return wasm;
3037}3022}
...@@ -3116,7 +3101,6 @@ fn parseArchive(wasm: *Wasm, obj: link.Input.Object) !void {...@@ -3116,7 +3101,6 @@ fn parseArchive(wasm: *Wasm, obj: link.Input.Object) !void {
31163101
3117pub fn deinit(wasm: *Wasm) void {3102pub fn deinit(wasm: *Wasm) void {
3118 const gpa = wasm.base.comp.gpa;3103 const gpa = wasm.base.comp.gpa;
3119 if (wasm.llvm_object) |llvm_object| llvm_object.deinit();
31203104
3121 wasm.navs_exe.deinit(gpa);3105 wasm.navs_exe.deinit(gpa);
3122 wasm.navs_obj.deinit(gpa);3106 wasm.navs_obj.deinit(gpa);
...@@ -3132,7 +3116,7 @@ pub fn deinit(wasm: *Wasm) void {...@@ -3132,7 +3116,7 @@ pub fn deinit(wasm: *Wasm) void {
31323116
3133 wasm.mir_instructions.deinit(gpa);3117 wasm.mir_instructions.deinit(gpa);
3134 wasm.mir_extra.deinit(gpa);3118 wasm.mir_extra.deinit(gpa);
3135 wasm.all_zcu_locals.deinit(gpa);3119 wasm.mir_locals.deinit(gpa);
31363120
3137 if (wasm.dwarf) |*dwarf| dwarf.deinit();3121 if (wasm.dwarf) |*dwarf| dwarf.deinit();
31383122
...@@ -3192,34 +3176,94 @@ pub fn deinit(wasm: *Wasm) void {...@@ -3192,34 +3176,94 @@ pub fn deinit(wasm: *Wasm) void {
3192 wasm.missing_exports.deinit(gpa);3176 wasm.missing_exports.deinit(gpa);
3193}3177}
31943178
3195pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Air.Liveness) !void {3179pub fn updateFunc(
3180 wasm: *Wasm,
3181 pt: Zcu.PerThread,
3182 func_index: InternPool.Index,
3183 any_mir: *const codegen.AnyMir,
3184) !void {
3196 if (build_options.skip_non_native and builtin.object_format != .wasm) {3185 if (build_options.skip_non_native and builtin.object_format != .wasm) {
3197 @panic("Attempted to compile for object format that was disabled by build configuration");3186 @panic("Attempted to compile for object format that was disabled by build configuration");
3198 }3187 }
3199 if (wasm.llvm_object) |llvm_object| return llvm_object.updateFunc(pt, func_index, air, liveness);
32003188
3201 dev.check(.wasm_backend);3189 dev.check(.wasm_backend);
32023190
3191 // This linker implementation only works with codegen backend `.stage2_wasm`.
3192 const mir = &any_mir.wasm;
3203 const zcu = pt.zcu;3193 const zcu = pt.zcu;
3204 const gpa = zcu.gpa;3194 const gpa = zcu.gpa;
3205 try wasm.functions.ensureUnusedCapacity(gpa, 1);
3206 try wasm.zcu_funcs.ensureUnusedCapacity(gpa, 1);
3207
3208 const ip = &zcu.intern_pool;3195 const ip = &zcu.intern_pool;
3196 const is_obj = zcu.comp.config.output_mode == .Obj;
3197 const target = &zcu.comp.root_mod.resolved_target.result;
3209 const owner_nav = zcu.funcInfo(func_index).owner_nav;3198 const owner_nav = zcu.funcInfo(func_index).owner_nav;
3210 log.debug("updateFunc {}", .{ip.getNav(owner_nav).fqn.fmt(ip)});3199 log.debug("updateFunc {}", .{ip.getNav(owner_nav).fqn.fmt(ip)});
32113200
3201 // For Wasm, we do not lower the MIR to code just yet. That lowering happens during `flush`,
3202 // after garbage collection, which can affect function and global indexes, which affects the
3203 // LEB integer encoding, which affects the output binary size.
3204
3205 // However, we do move the MIR into a more efficient in-memory representation, where the arrays
3206 // for all functions are packed together rather than keeping them each in their own `Mir`.
3207 const mir_instructions_off: u32 = @intCast(wasm.mir_instructions.len);
3208 const mir_extra_off: u32 = @intCast(wasm.mir_extra.items.len);
3209 const mir_locals_off: u32 = @intCast(wasm.mir_locals.items.len);
3210 {
3211 // Copying MultiArrayList data is a little non-trivial. Resize, then memcpy both slices.
3212 const old_len = wasm.mir_instructions.len;
3213 try wasm.mir_instructions.resize(gpa, old_len + mir.instructions.len);
3214 const dest_slice = wasm.mir_instructions.slice().subslice(old_len, mir.instructions.len);
3215 const src_slice = mir.instructions;
3216 @memcpy(dest_slice.items(.tag), src_slice.items(.tag));
3217 @memcpy(dest_slice.items(.data), src_slice.items(.data));
3218 }
3219 try wasm.mir_extra.appendSlice(gpa, mir.extra);
3220 try wasm.mir_locals.appendSlice(gpa, mir.locals);
3221
3222 // We also need to populate some global state from `mir`.
3223 try wasm.zcu_indirect_function_set.ensureUnusedCapacity(gpa, mir.indirect_function_set.count());
3224 for (mir.indirect_function_set.keys()) |nav| wasm.zcu_indirect_function_set.putAssumeCapacity(nav, {});
3225 for (mir.func_tys.keys()) |func_ty| {
3226 const fn_info = zcu.typeToFunc(.fromInterned(func_ty)).?;
3227 _ = try wasm.internFunctionType(fn_info.cc, fn_info.param_types.get(ip), .fromInterned(fn_info.return_type), target);
3228 }
3229 wasm.error_name_table_ref_count += mir.error_name_table_ref_count;
3230 // We need to populate UAV data. In theory, we can lower the UAV values while we fill `mir.uavs`.
3231 // However, lowering the data might cause *more* UAVs to be created, and mixing them up would be
3232 // a headache. So instead, just write `undefined` placeholder code and use the `ZcuDataStarts`.
3212 const zds: ZcuDataStarts = .init(wasm);3233 const zds: ZcuDataStarts = .init(wasm);
3234 for (mir.uavs.keys(), mir.uavs.values()) |uav_val, uav_align| {
3235 if (uav_align != .none) {
3236 const gop = try wasm.overaligned_uavs.getOrPut(gpa, uav_val);
3237 gop.value_ptr.* = if (gop.found_existing) gop.value_ptr.maxStrict(uav_align) else uav_align;
3238 }
3239 if (is_obj) {
3240 const gop = try wasm.uavs_obj.getOrPut(gpa, uav_val);
3241 if (!gop.found_existing) gop.value_ptr.* = undefined; // `zds` handles lowering
3242 } else {
3243 const gop = try wasm.uavs_exe.getOrPut(gpa, uav_val);
3244 if (!gop.found_existing) gop.value_ptr.* = .{
3245 .code = undefined, // `zds` handles lowering
3246 .count = 0,
3247 };
3248 gop.value_ptr.count += 1;
3249 }
3250 }
3251 try zds.finish(wasm, pt); // actually generates the UAVs
3252
3253 try wasm.functions.ensureUnusedCapacity(gpa, 1);
3254 try wasm.zcu_funcs.ensureUnusedCapacity(gpa, 1);
32133255
3214 // This converts AIR to MIR but does not yet lower to wasm code.3256 // This converts AIR to MIR but does not yet lower to wasm code.
3215 // That lowering happens during `flush`, after garbage collection, which3257 wasm.zcu_funcs.putAssumeCapacity(func_index, .{ .function = .{
3216 // can affect function and global indexes, which affects the LEB integer3258 .instructions_off = mir_instructions_off,
3217 // encoding, which affects the output binary size.3259 .instructions_len = @intCast(mir.instructions.len),
3218 const function = try CodeGen.function(wasm, pt, func_index, air, liveness);3260 .extra_off = mir_extra_off,
3219 wasm.zcu_funcs.putAssumeCapacity(func_index, .{ .function = function });3261 .extra_len = @intCast(mir.extra.len),
3262 .locals_off = mir_locals_off,
3263 .locals_len = @intCast(mir.locals.len),
3264 .prologue = mir.prologue,
3265 } });
3220 wasm.functions.putAssumeCapacity(.pack(wasm, .{ .zcu_func = @enumFromInt(wasm.zcu_funcs.entries.len - 1) }), {});3266 wasm.functions.putAssumeCapacity(.pack(wasm, .{ .zcu_func = @enumFromInt(wasm.zcu_funcs.entries.len - 1) }), {});
3221
3222 try zds.finish(wasm, pt);
3223}3267}
32243268
3225// Generate code for the "Nav", storing it in memory to be later written to3269// Generate code for the "Nav", storing it in memory to be later written to
...@@ -3228,7 +3272,6 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index...@@ -3228,7 +3272,6 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index
3228 if (build_options.skip_non_native and builtin.object_format != .wasm) {3272 if (build_options.skip_non_native and builtin.object_format != .wasm) {
3229 @panic("Attempted to compile for object format that was disabled by build configuration");3273 @panic("Attempted to compile for object format that was disabled by build configuration");
3230 }3274 }
3231 if (wasm.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav_index);
3232 const zcu = pt.zcu;3275 const zcu = pt.zcu;
3233 const ip = &zcu.intern_pool;3276 const ip = &zcu.intern_pool;
3234 const nav = ip.getNav(nav_index);3277 const nav = ip.getNav(nav_index);
...@@ -3308,8 +3351,6 @@ pub fn deleteExport(...@@ -3308,8 +3351,6 @@ pub fn deleteExport(
3308 exported: Zcu.Exported,3351 exported: Zcu.Exported,
3309 name: InternPool.NullTerminatedString,3352 name: InternPool.NullTerminatedString,
3310) void {3353) void {
3311 if (wasm.llvm_object != null) return;
3312
3313 const zcu = wasm.base.comp.zcu.?;3354 const zcu = wasm.base.comp.zcu.?;
3314 const ip = &zcu.intern_pool;3355 const ip = &zcu.intern_pool;
3315 const name_slice = name.toSlice(ip);3356 const name_slice = name.toSlice(ip);
...@@ -3332,7 +3373,6 @@ pub fn updateExports(...@@ -3332,7 +3373,6 @@ pub fn updateExports(
3332 if (build_options.skip_non_native and builtin.object_format != .wasm) {3373 if (build_options.skip_non_native and builtin.object_format != .wasm) {
3333 @panic("Attempted to compile for object format that was disabled by build configuration");3374 @panic("Attempted to compile for object format that was disabled by build configuration");
3334 }3375 }
3335 if (wasm.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices);
33363376
3337 const zcu = pt.zcu;3377 const zcu = pt.zcu;
3338 const gpa = zcu.gpa;3378 const gpa = zcu.gpa;
...@@ -3379,21 +3419,6 @@ pub fn loadInput(wasm: *Wasm, input: link.Input) !void {...@@ -3379,21 +3419,6 @@ pub fn loadInput(wasm: *Wasm, input: link.Input) !void {
3379 }3419 }
3380}3420}
33813421
3382pub fn flush(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
3383 const comp = wasm.base.comp;
3384 const use_lld = build_options.have_llvm and comp.config.use_lld;
3385 const diags = &comp.link_diags;
3386
3387 if (use_lld) {
3388 return wasm.linkWithLLD(arena, tid, prog_node) catch |err| switch (err) {
3389 error.OutOfMemory => return error.OutOfMemory,
3390 error.LinkFailure => return error.LinkFailure,
3391 else => |e| return diags.fail("failed to link with LLD: {s}", .{@errorName(e)}),
3392 };
3393 }
3394 return wasm.flushModule(arena, tid, prog_node);
3395}
3396
3397pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!void {3422pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!void {
3398 const tracy = trace(@src());3423 const tracy = trace(@src());
3399 defer tracy.end();3424 defer tracy.end();
...@@ -3785,37 +3810,25 @@ fn markTable(wasm: *Wasm, i: ObjectTableIndex) link.File.FlushError!void {...@@ -3785,37 +3810,25 @@ fn markTable(wasm: *Wasm, i: ObjectTableIndex) link.File.FlushError!void {
3785 try wasm.tables.put(wasm.base.comp.gpa, .fromObjectTable(i), {});3810 try wasm.tables.put(wasm.base.comp.gpa, .fromObjectTable(i), {});
3786}3811}
37873812
3788pub fn flushModule(3813pub fn flush(
3789 wasm: *Wasm,3814 wasm: *Wasm,
3790 arena: Allocator,3815 arena: Allocator,
3791 tid: Zcu.PerThread.Id,3816 tid: Zcu.PerThread.Id,
3792 prog_node: std.Progress.Node,3817 prog_node: std.Progress.Node,
3793) link.File.FlushError!void {3818) link.File.FlushError!void {
3794 // The goal is to never use this because it's only needed if we need to3819 // The goal is to never use this because it's only needed if we need to
3795 // write to InternPool, but flushModule is too late to be writing to the3820 // write to InternPool, but flush is too late to be writing to the
3796 // InternPool.3821 // InternPool.
3797 _ = tid;3822 _ = tid;
3798 const comp = wasm.base.comp;3823 const comp = wasm.base.comp;
3799 const use_lld = build_options.have_llvm and comp.config.use_lld;
3800 const diags = &comp.link_diags;3824 const diags = &comp.link_diags;
3801 const gpa = comp.gpa;3825 const gpa = comp.gpa;
38023826
3803 if (wasm.llvm_object) |llvm_object| {
3804 try wasm.base.emitLlvmObject(arena, llvm_object, prog_node);
3805 if (use_lld) return;
3806 }
3807
3808 if (comp.verbose_link) Compilation.dump_argv(wasm.dump_argv_list.items);3827 if (comp.verbose_link) Compilation.dump_argv(wasm.dump_argv_list.items);
38093828
3810 if (wasm.base.zcu_object_sub_path) |path| {3829 if (wasm.base.zcu_object_basename) |raw| {
3811 const module_obj_path: Path = .{3830 const zcu_obj_path: Path = try comp.resolveEmitPathFlush(arena, .temp, raw);
3812 .root_dir = wasm.base.emit.root_dir,3831 openParseObjectReportingFailure(wasm, zcu_obj_path);
3813 .sub_path = if (fs.path.dirname(wasm.base.emit.sub_path)) |dirname|
3814 try fs.path.join(arena, &.{ dirname, path })
3815 else
3816 path,
3817 };
3818 openParseObjectReportingFailure(wasm, module_obj_path);
3819 try prelink(wasm, prog_node);3832 try prelink(wasm, prog_node);
3820 }3833 }
38213834
...@@ -3850,432 +3863,6 @@ pub fn flushModule(...@@ -3850,432 +3863,6 @@ pub fn flushModule(
3850 };3863 };
3851}3864}
38523865
3853fn linkWithLLD(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
3854 dev.check(.lld_linker);
3855
3856 const tracy = trace(@src());
3857 defer tracy.end();
3858
3859 const comp = wasm.base.comp;
3860 const diags = &comp.link_diags;
3861 const shared_memory = comp.config.shared_memory;
3862 const export_memory = comp.config.export_memory;
3863 const import_memory = comp.config.import_memory;
3864 const target = comp.root_mod.resolved_target.result;
3865
3866 const gpa = comp.gpa;
3867
3868 const directory = wasm.base.emit.root_dir; // Just an alias to make it shorter to type.
3869 const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.emit.sub_path});
3870
3871 // If there is no Zig code to compile, then we should skip flushing the output file because it
3872 // will not be part of the linker line anyway.
3873 const module_obj_path: ?[]const u8 = if (comp.zcu != null) blk: {
3874 try wasm.flushModule(arena, tid, prog_node);
3875
3876 if (fs.path.dirname(full_out_path)) |dirname| {
3877 break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? });
3878 } else {
3879 break :blk wasm.base.zcu_object_sub_path.?;
3880 }
3881 } else null;
3882
3883 const sub_prog_node = prog_node.start("LLD Link", 0);
3884 defer sub_prog_node.end();
3885
3886 const is_obj = comp.config.output_mode == .Obj;
3887 const compiler_rt_path: ?Path = blk: {
3888 if (comp.compiler_rt_lib) |lib| break :blk lib.full_object_path;
3889 if (comp.compiler_rt_obj) |obj| break :blk obj.full_object_path;
3890 break :blk null;
3891 };
3892 const ubsan_rt_path: ?Path = blk: {
3893 if (comp.ubsan_rt_lib) |lib| break :blk lib.full_object_path;
3894 if (comp.ubsan_rt_obj) |obj| break :blk obj.full_object_path;
3895 break :blk null;
3896 };
3897
3898 const id_symlink_basename = "lld.id";
3899
3900 var man: Cache.Manifest = undefined;
3901 defer if (!wasm.base.disable_lld_caching) man.deinit();
3902
3903 var digest: [Cache.hex_digest_len]u8 = undefined;
3904
3905 if (!wasm.base.disable_lld_caching) {
3906 man = comp.cache_parent.obtain();
3907
3908 // We are about to obtain this lock, so here we give other processes a chance first.
3909 wasm.base.releaseLock();
3910
3911 comptime assert(Compilation.link_hash_implementation_version == 14);
3912
3913 try link.hashInputs(&man, comp.link_inputs);
3914 for (comp.c_object_table.keys()) |key| {
3915 _ = try man.addFilePath(key.status.success.object_path, null);
3916 }
3917 try man.addOptionalFile(module_obj_path);
3918 try man.addOptionalFilePath(compiler_rt_path);
3919 try man.addOptionalFilePath(ubsan_rt_path);
3920 man.hash.addOptionalBytes(wasm.entry_name.slice(wasm));
3921 man.hash.add(wasm.base.stack_size);
3922 man.hash.add(wasm.base.build_id);
3923 man.hash.add(import_memory);
3924 man.hash.add(export_memory);
3925 man.hash.add(wasm.import_table);
3926 man.hash.add(wasm.export_table);
3927 man.hash.addOptional(wasm.initial_memory);
3928 man.hash.addOptional(wasm.max_memory);
3929 man.hash.add(shared_memory);
3930 man.hash.addOptional(wasm.global_base);
3931 man.hash.addListOfBytes(wasm.export_symbol_names);
3932 // strip does not need to go into the linker hash because it is part of the hash namespace
3933
3934 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
3935 _ = try man.hit();
3936 digest = man.final();
3937
3938 var prev_digest_buf: [digest.len]u8 = undefined;
3939 const prev_digest: []u8 = Cache.readSmallFile(
3940 directory.handle,
3941 id_symlink_basename,
3942 &prev_digest_buf,
3943 ) catch |err| blk: {
3944 log.debug("WASM LLD new_digest={s} error: {s}", .{ std.fmt.fmtSliceHexLower(&digest), @errorName(err) });
3945 // Handle this as a cache miss.
3946 break :blk prev_digest_buf[0..0];
3947 };
3948 if (mem.eql(u8, prev_digest, &digest)) {
3949 log.debug("WASM LLD digest={s} match - skipping invocation", .{std.fmt.fmtSliceHexLower(&digest)});
3950 // Hot diggity dog! The output binary is already there.
3951 wasm.base.lock = man.toOwnedLock();
3952 return;
3953 }
3954 log.debug("WASM LLD prev_digest={s} new_digest={s}", .{ std.fmt.fmtSliceHexLower(prev_digest), std.fmt.fmtSliceHexLower(&digest) });
3955
3956 // We are about to change the output file to be different, so we invalidate the build hash now.
3957 directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) {
3958 error.FileNotFound => {},
3959 else => |e| return e,
3960 };
3961 }
3962
3963 if (is_obj) {
3964 // LLD's WASM driver does not support the equivalent of `-r` so we do a simple file copy
3965 // here. TODO: think carefully about how we can avoid this redundant operation when doing
3966 // build-obj. See also the corresponding TODO in linkAsArchive.
3967 const the_object_path = blk: {
3968 if (link.firstObjectInput(comp.link_inputs)) |obj| break :blk obj.path;
3969
3970 if (comp.c_object_table.count() != 0)
3971 break :blk comp.c_object_table.keys()[0].status.success.object_path;
3972
3973 if (module_obj_path) |p|
3974 break :blk Path.initCwd(p);
3975
3976 // TODO I think this is unreachable. Audit this situation when solving the above TODO
3977 // regarding eliding redundant object -> object transformations.
3978 return error.NoObjectsToLink;
3979 };
3980 try fs.Dir.copyFile(
3981 the_object_path.root_dir.handle,
3982 the_object_path.sub_path,
3983 directory.handle,
3984 wasm.base.emit.sub_path,
3985 .{},
3986 );
3987 } else {
3988 // Create an LLD command line and invoke it.
3989 var argv = std.ArrayList([]const u8).init(gpa);
3990 defer argv.deinit();
3991 // We will invoke ourselves as a child process to gain access to LLD.
3992 // This is necessary because LLD does not behave properly as a library -
3993 // it calls exit() and does not reset all global data between invocations.
3994 const linker_command = "wasm-ld";
3995 try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command });
3996 try argv.append("--error-limit=0");
3997
3998 if (comp.config.lto != .none) {
3999 switch (comp.root_mod.optimize_mode) {
4000 .Debug => {},
4001 .ReleaseSmall => try argv.append("-O2"),
4002 .ReleaseFast, .ReleaseSafe => try argv.append("-O3"),
4003 }
4004 }
4005
4006 if (import_memory) {
4007 try argv.append("--import-memory");
4008 }
4009
4010 if (export_memory) {
4011 try argv.append("--export-memory");
4012 }
4013
4014 if (wasm.import_table) {
4015 assert(!wasm.export_table);
4016 try argv.append("--import-table");
4017 }
4018
4019 if (wasm.export_table) {
4020 assert(!wasm.import_table);
4021 try argv.append("--export-table");
4022 }
4023
4024 // For wasm-ld we only need to specify '--no-gc-sections' when the user explicitly
4025 // specified it as garbage collection is enabled by default.
4026 if (!wasm.base.gc_sections) {
4027 try argv.append("--no-gc-sections");
4028 }
4029
4030 if (comp.config.debug_format == .strip) {
4031 try argv.append("-s");
4032 }
4033
4034 if (wasm.initial_memory) |initial_memory| {
4035 const arg = try std.fmt.allocPrint(arena, "--initial-memory={d}", .{initial_memory});
4036 try argv.append(arg);
4037 }
4038
4039 if (wasm.max_memory) |max_memory| {
4040 const arg = try std.fmt.allocPrint(arena, "--max-memory={d}", .{max_memory});
4041 try argv.append(arg);
4042 }
4043
4044 if (shared_memory) {
4045 try argv.append("--shared-memory");
4046 }
4047
4048 if (wasm.global_base) |global_base| {
4049 const arg = try std.fmt.allocPrint(arena, "--global-base={d}", .{global_base});
4050 try argv.append(arg);
4051 } else {
4052 // We prepend it by default, so when a stack overflow happens the runtime will trap correctly,
4053 // rather than silently overwrite all global declarations. See https://github.com/ziglang/zig/issues/4496
4054 //
4055 // The user can overwrite this behavior by setting the global-base
4056 try argv.append("--stack-first");
4057 }
4058
4059 // Users are allowed to specify which symbols they want to export to the wasm host.
4060 for (wasm.export_symbol_names) |symbol_name| {
4061 const arg = try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name});
4062 try argv.append(arg);
4063 }
4064
4065 if (comp.config.rdynamic) {
4066 try argv.append("--export-dynamic");
4067 }
4068
4069 if (wasm.entry_name.slice(wasm)) |entry_name| {
4070 try argv.appendSlice(&.{ "--entry", entry_name });
4071 } else {
4072 try argv.append("--no-entry");
4073 }
4074
4075 try argv.appendSlice(&.{
4076 "-z",
4077 try std.fmt.allocPrint(arena, "stack-size={d}", .{wasm.base.stack_size}),
4078 });
4079
4080 switch (wasm.base.build_id) {
4081 .none => try argv.append("--build-id=none"),
4082 .fast, .uuid, .sha1 => try argv.append(try std.fmt.allocPrint(arena, "--build-id={s}", .{
4083 @tagName(wasm.base.build_id),
4084 })),
4085 .hexstring => |hs| try argv.append(try std.fmt.allocPrint(arena, "--build-id=0x{s}", .{
4086 std.fmt.fmtSliceHexLower(hs.toSlice()),
4087 })),
4088 .md5 => {},
4089 }
4090
4091 if (wasm.import_symbols) {
4092 try argv.append("--allow-undefined");
4093 }
4094
4095 if (comp.config.output_mode == .Lib and comp.config.link_mode == .dynamic) {
4096 try argv.append("--shared");
4097 }
4098 if (comp.config.pie) {
4099 try argv.append("--pie");
4100 }
4101
4102 try argv.appendSlice(&.{ "-o", full_out_path });
4103
4104 if (target.cpu.arch == .wasm64) {
4105 try argv.append("-mwasm64");
4106 }
4107
4108 const is_exe_or_dyn_lib = comp.config.output_mode == .Exe or
4109 (comp.config.output_mode == .Lib and comp.config.link_mode == .dynamic);
4110
4111 if (comp.config.link_libc and is_exe_or_dyn_lib) {
4112 if (target.os.tag == .wasi) {
4113 for (comp.wasi_emulated_libs) |crt_file| {
4114 try argv.append(try comp.crtFileAsString(
4115 arena,
4116 wasi_libc.emulatedLibCRFileLibName(crt_file),
4117 ));
4118 }
4119
4120 try argv.append(try comp.crtFileAsString(
4121 arena,
4122 wasi_libc.execModelCrtFileFullName(comp.config.wasi_exec_model),
4123 ));
4124 try argv.append(try comp.crtFileAsString(arena, "libc.a"));
4125 }
4126
4127 if (comp.zigc_static_lib) |zigc| {
4128 try argv.append(try zigc.full_object_path.toString(arena));
4129 }
4130
4131 if (comp.config.link_libcpp) {
4132 try argv.append(try comp.libcxx_static_lib.?.full_object_path.toString(arena));
4133 try argv.append(try comp.libcxxabi_static_lib.?.full_object_path.toString(arena));
4134 }
4135 }
4136
4137 // Positional arguments to the linker such as object files.
4138 var whole_archive = false;
4139 for (comp.link_inputs) |link_input| switch (link_input) {
4140 .object, .archive => |obj| {
4141 if (obj.must_link and !whole_archive) {
4142 try argv.append("-whole-archive");
4143 whole_archive = true;
4144 } else if (!obj.must_link and whole_archive) {
4145 try argv.append("-no-whole-archive");
4146 whole_archive = false;
4147 }
4148 try argv.append(try obj.path.toString(arena));
4149 },
4150 .dso => |dso| {
4151 try argv.append(try dso.path.toString(arena));
4152 },
4153 .dso_exact => unreachable,
4154 .res => unreachable,
4155 };
4156 if (whole_archive) {
4157 try argv.append("-no-whole-archive");
4158 whole_archive = false;
4159 }
4160
4161 for (comp.c_object_table.keys()) |key| {
4162 try argv.append(try key.status.success.object_path.toString(arena));
4163 }
4164 if (module_obj_path) |p| {
4165 try argv.append(p);
4166 }
4167
4168 if (compiler_rt_path) |p| {
4169 try argv.append(try p.toString(arena));
4170 }
4171
4172 if (ubsan_rt_path) |p| {
4173 try argv.append(try p.toStringZ(arena));
4174 }
4175
4176 if (comp.verbose_link) {
4177 // Skip over our own name so that the LLD linker name is the first argv item.
4178 Compilation.dump_argv(argv.items[1..]);
4179 }
4180
4181 if (std.process.can_spawn) {
4182 // If possible, we run LLD as a child process because it does not always
4183 // behave properly as a library, unfortunately.
4184 // https://github.com/ziglang/zig/issues/3825
4185 var child = std.process.Child.init(argv.items, arena);
4186 if (comp.clang_passthrough_mode) {
4187 child.stdin_behavior = .Inherit;
4188 child.stdout_behavior = .Inherit;
4189 child.stderr_behavior = .Inherit;
4190
4191 const term = child.spawnAndWait() catch |err| {
4192 log.err("failed to spawn (passthrough mode) LLD {s}: {s}", .{ argv.items[0], @errorName(err) });
4193 return error.UnableToSpawnWasm;
4194 };
4195 switch (term) {
4196 .Exited => |code| {
4197 if (code != 0) {
4198 std.process.exit(code);
4199 }
4200 },
4201 else => std.process.abort(),
4202 }
4203 } else {
4204 child.stdin_behavior = .Ignore;
4205 child.stdout_behavior = .Ignore;
4206 child.stderr_behavior = .Pipe;
4207
4208 try child.spawn();
4209
4210 const stderr = try child.stderr.?.reader().readAllAlloc(arena, std.math.maxInt(usize));
4211
4212 const term = child.wait() catch |err| {
4213 log.err("failed to spawn LLD {s}: {s}", .{ argv.items[0], @errorName(err) });
4214 return error.UnableToSpawnWasm;
4215 };
4216
4217 switch (term) {
4218 .Exited => |code| {
4219 if (code != 0) {
4220 diags.lockAndParseLldStderr(linker_command, stderr);
4221 return error.LinkFailure;
4222 }
4223 },
4224 else => {
4225 return diags.fail("{s} terminated with stderr:\n{s}", .{ argv.items[0], stderr });
4226 },
4227 }
4228
4229 if (stderr.len != 0) {
4230 log.warn("unexpected LLD stderr:\n{s}", .{stderr});
4231 }
4232 }
4233 } else {
4234 const exit_code = try lldMain(arena, argv.items, false);
4235 if (exit_code != 0) {
4236 if (comp.clang_passthrough_mode) {
4237 std.process.exit(exit_code);
4238 } else {
4239 return diags.fail("{s} returned exit code {d}:\n{s}", .{ argv.items[0], exit_code });
4240 }
4241 }
4242 }
4243
4244 // Give +x to the .wasm file if it is an executable and the OS is WASI.
4245 // Some systems may be configured to execute such binaries directly. Even if that
4246 // is not the case, it means we will get "exec format error" when trying to run
4247 // it, and then can react to that in the same way as trying to run an ELF file
4248 // from a foreign CPU architecture.
4249 if (fs.has_executable_bit and target.os.tag == .wasi and
4250 comp.config.output_mode == .Exe)
4251 {
4252 // TODO: what's our strategy for reporting linker errors from this function?
4253 // report a nice error here with the file path if it fails instead of
4254 // just returning the error code.
4255 // chmod does not interact with umask, so we use a conservative -rwxr--r-- here.
4256 std.posix.fchmodat(fs.cwd().fd, full_out_path, 0o744, 0) catch |err| switch (err) {
4257 error.OperationNotSupported => unreachable, // Not a symlink.
4258 else => |e| return e,
4259 };
4260 }
4261 }
4262
4263 if (!wasm.base.disable_lld_caching) {
4264 // Update the file with the digest. If it fails we can continue; it only
4265 // means that the next invocation will have an unnecessary cache miss.
4266 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
4267 log.warn("failed to save linking hash digest symlink: {s}", .{@errorName(err)});
4268 };
4269 // Again failure here only means an unnecessary cache miss.
4270 man.writeManifest() catch |err| {
4271 log.warn("failed to write cache manifest when linking: {s}", .{@errorName(err)});
4272 };
4273 // We hang on to this lock so that the output file path can be used without
4274 // other processes clobbering it.
4275 wasm.base.lock = man.toOwnedLock();
4276 }
4277}
4278
4279fn defaultEntrySymbolName(3866fn defaultEntrySymbolName(
4280 preloaded_strings: *const PreloadedStrings,3867 preloaded_strings: *const PreloadedStrings,
4281 wasi_exec_model: std.builtin.WasiExecModel,3868 wasi_exec_model: std.builtin.WasiExecModel,
...@@ -4465,58 +4052,54 @@ pub fn symbolNameIndex(wasm: *Wasm, name: String) Allocator.Error!SymbolTableInd...@@ -4465,58 +4052,54 @@ pub fn symbolNameIndex(wasm: *Wasm, name: String) Allocator.Error!SymbolTableInd
4465 return @enumFromInt(gop.index);4052 return @enumFromInt(gop.index);
4466}4053}
44674054
4468pub fn refUavObj(wasm: *Wasm, ip_index: InternPool.Index, orig_ptr_ty: InternPool.Index) !UavsObjIndex {4055pub fn addUavReloc(
4469 const comp = wasm.base.comp;4056 wasm: *Wasm,
4470 const zcu = comp.zcu.?;4057 reloc_offset: usize,
4471 const ip = &zcu.intern_pool;4058 uav_val: InternPool.Index,
4472 const gpa = comp.gpa;4059 orig_ptr_ty: InternPool.Index,
4473 assert(comp.config.output_mode == .Obj);4060 addend: u32,
44744061) !void {
4475 if (orig_ptr_ty != .none) {
4476 const abi_alignment = Zcu.Type.fromInterned(ip.typeOf(ip_index)).abiAlignment(zcu);
4477 const explicit_alignment = ip.indexToKey(orig_ptr_ty).ptr_type.flags.alignment;
4478 if (explicit_alignment.compare(.gt, abi_alignment)) {
4479 const gop = try wasm.overaligned_uavs.getOrPut(gpa, ip_index);
4480 gop.value_ptr.* = if (gop.found_existing) gop.value_ptr.maxStrict(explicit_alignment) else explicit_alignment;
4481 }
4482 }
4483
4484 const gop = try wasm.uavs_obj.getOrPut(gpa, ip_index);
4485 if (!gop.found_existing) gop.value_ptr.* = .{
4486 // Lowering the value is delayed to avoid recursion.
4487 .code = undefined,
4488 .relocs = undefined,
4489 };
4490 return @enumFromInt(gop.index);
4491}
4492
4493pub fn refUavExe(wasm: *Wasm, ip_index: InternPool.Index, orig_ptr_ty: InternPool.Index) !UavsExeIndex {
4494 const comp = wasm.base.comp;4062 const comp = wasm.base.comp;
4495 const zcu = comp.zcu.?;4063 const zcu = comp.zcu.?;
4496 const ip = &zcu.intern_pool;4064 const ip = &zcu.intern_pool;
4497 const gpa = comp.gpa;4065 const gpa = comp.gpa;
4498 assert(comp.config.output_mode != .Obj);
44994066
4500 if (orig_ptr_ty != .none) {4067 @"align": {
4501 const abi_alignment = Zcu.Type.fromInterned(ip.typeOf(ip_index)).abiAlignment(zcu);4068 const ptr_type = ip.indexToKey(orig_ptr_ty).ptr_type;
4502 const explicit_alignment = ip.indexToKey(orig_ptr_ty).ptr_type.flags.alignment;4069 const this_align = ptr_type.flags.alignment;
4503 if (explicit_alignment.compare(.gt, abi_alignment)) {4070 if (this_align == .none) break :@"align";
4504 const gop = try wasm.overaligned_uavs.getOrPut(gpa, ip_index);4071 const abi_align = Zcu.Type.fromInterned(ptr_type.child).abiAlignment(zcu);
4505 gop.value_ptr.* = if (gop.found_existing) gop.value_ptr.maxStrict(explicit_alignment) else explicit_alignment;4072 if (this_align.compare(.lte, abi_align)) break :@"align";
4506 }4073 const gop = try wasm.overaligned_uavs.getOrPut(gpa, uav_val);
4507 }4074 gop.value_ptr.* = if (gop.found_existing) gop.value_ptr.maxStrict(this_align) else this_align;
45084075 }
4509 const gop = try wasm.uavs_exe.getOrPut(gpa, ip_index);4076
4510 if (gop.found_existing) {4077 if (comp.config.output_mode == .Obj) {
4511 gop.value_ptr.count += 1;4078 const gop = try wasm.uavs_obj.getOrPut(gpa, uav_val);
4079 if (!gop.found_existing) gop.value_ptr.* = undefined; // to avoid recursion, `ZcuDataStarts` will lower the value later
4080 try wasm.out_relocs.append(gpa, .{
4081 .offset = @intCast(reloc_offset),
4082 .pointee = .{ .symbol_index = try wasm.uavSymbolIndex(uav_val) },
4083 .tag = switch (wasm.pointerSize()) {
4084 32 => .memory_addr_i32,
4085 64 => .memory_addr_i64,
4086 else => unreachable,
4087 },
4088 .addend = @intCast(addend),
4089 });
4512 } else {4090 } else {
4513 gop.value_ptr.* = .{4091 const gop = try wasm.uavs_exe.getOrPut(gpa, uav_val);
4514 // Lowering the value is delayed to avoid recursion.4092 if (!gop.found_existing) gop.value_ptr.* = .{
4515 .code = undefined,4093 .code = undefined, // to avoid recursion, `ZcuDataStarts` will lower the value later
4516 .count = 1,4094 .count = 0,
4517 };4095 };
4096 gop.value_ptr.count += 1;
4097 try wasm.uav_fixups.append(gpa, .{
4098 .uavs_exe_index = @enumFromInt(gop.index),
4099 .offset = @intCast(reloc_offset),
4100 .addend = addend,
4101 });
4518 }4102 }
4519 return @enumFromInt(gop.index);
4520}4103}
45214104
4522pub fn refNavObj(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsObjIndex {4105pub fn refNavObj(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsObjIndex {
...@@ -4550,10 +4133,11 @@ pub fn refNavExe(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsExeIndex {...@@ -4550,10 +4133,11 @@ pub fn refNavExe(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsExeIndex {
4550}4133}
45514134
4552/// Asserts it is called after `Flush.data_segments` is fully populated and sorted.4135/// Asserts it is called after `Flush.data_segments` is fully populated and sorted.
4553pub fn uavAddr(wasm: *Wasm, uav_index: UavsExeIndex) u32 {4136pub fn uavAddr(wasm: *Wasm, ip_index: InternPool.Index) u32 {
4554 assert(wasm.flush_buffer.memory_layout_finished);4137 assert(wasm.flush_buffer.memory_layout_finished);
4555 const comp = wasm.base.comp;4138 const comp = wasm.base.comp;
4556 assert(comp.config.output_mode != .Obj);4139 assert(comp.config.output_mode != .Obj);
4140 const uav_index: UavsExeIndex = @enumFromInt(wasm.uavs_exe.getIndex(ip_index).?);
4557 const ds_id: DataSegmentId = .pack(wasm, .{ .uav_exe = uav_index });4141 const ds_id: DataSegmentId = .pack(wasm, .{ .uav_exe = uav_index });
4558 return wasm.flush_buffer.data_segments.get(ds_id).?;4142 return wasm.flush_buffer.data_segments.get(ds_id).?;
4559}4143}
src/link/Wasm/Flush.zig+16-1
...@@ -9,6 +9,7 @@ const Alignment = Wasm.Alignment;...@@ -9,6 +9,7 @@ const Alignment = Wasm.Alignment;
9const String = Wasm.String;9const String = Wasm.String;
10const Relocation = Wasm.Relocation;10const Relocation = Wasm.Relocation;
11const InternPool = @import("../../InternPool.zig");11const InternPool = @import("../../InternPool.zig");
12const Mir = @import("../../arch/wasm/Mir.zig");
1213
13const build_options = @import("build_options");14const build_options = @import("build_options");
1415
...@@ -868,7 +869,21 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -868,7 +869,21 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
868 .enum_type => {869 .enum_type => {
869 try emitTagNameFunction(wasm, binary_bytes, f.data_segments.get(.__zig_tag_name_table).?, i.value(wasm).tag_name.table_index, ip_index);870 try emitTagNameFunction(wasm, binary_bytes, f.data_segments.get(.__zig_tag_name_table).?, i.value(wasm).tag_name.table_index, ip_index);
870 },871 },
871 else => try i.value(wasm).function.lower(wasm, binary_bytes),872 else => {
873 const func = i.value(wasm).function;
874 const mir: Mir = .{
875 .instructions = wasm.mir_instructions.slice().subslice(func.instructions_off, func.instructions_len),
876 .extra = wasm.mir_extra.items[func.extra_off..][0..func.extra_len],
877 .locals = wasm.mir_locals.items[func.locals_off..][0..func.locals_len],
878 .prologue = func.prologue,
879 // These fields are unused by `lower`.
880 .uavs = undefined,
881 .indirect_function_set = undefined,
882 .func_tys = undefined,
883 .error_name_table_ref_count = undefined,
884 };
885 try mir.lower(wasm, binary_bytes);
886 },
872 }887 }
873 },888 },
874 };889 };
src/link/Xcoff.zig+21-28
...@@ -13,14 +13,12 @@ const Path = std.Build.Cache.Path;...@@ -13,14 +13,12 @@ const Path = std.Build.Cache.Path;
13const Zcu = @import("../Zcu.zig");13const Zcu = @import("../Zcu.zig");
14const InternPool = @import("../InternPool.zig");14const InternPool = @import("../InternPool.zig");
15const Compilation = @import("../Compilation.zig");15const Compilation = @import("../Compilation.zig");
16const codegen = @import("../codegen.zig");
16const link = @import("../link.zig");17const link = @import("../link.zig");
17const trace = @import("../tracy.zig").trace;18const trace = @import("../tracy.zig").trace;
18const build_options = @import("build_options");19const build_options = @import("build_options");
19const Air = @import("../Air.zig");
20const LlvmObject = @import("../codegen/llvm.zig").Object;
2120
22base: link.File,21base: link.File,
23llvm_object: LlvmObject.Ptr,
2422
25pub fn createEmpty(23pub fn createEmpty(
26 arena: Allocator,24 arena: Allocator,
...@@ -36,23 +34,20 @@ pub fn createEmpty(...@@ -36,23 +34,20 @@ pub fn createEmpty(
36 assert(!use_lld); // Caught by Compilation.Config.resolve.34 assert(!use_lld); // Caught by Compilation.Config.resolve.
37 assert(target.os.tag == .aix); // Caught by Compilation.Config.resolve.35 assert(target.os.tag == .aix); // Caught by Compilation.Config.resolve.
3836
39 const llvm_object = try LlvmObject.create(arena, comp);
40 const xcoff = try arena.create(Xcoff);37 const xcoff = try arena.create(Xcoff);
41 xcoff.* = .{38 xcoff.* = .{
42 .base = .{39 .base = .{
43 .tag = .xcoff,40 .tag = .xcoff,
44 .comp = comp,41 .comp = comp,
45 .emit = emit,42 .emit = emit,
46 .zcu_object_sub_path = emit.sub_path,43 .zcu_object_basename = emit.sub_path,
47 .gc_sections = options.gc_sections orelse false,44 .gc_sections = options.gc_sections orelse false,
48 .print_gc_sections = options.print_gc_sections,45 .print_gc_sections = options.print_gc_sections,
49 .stack_size = options.stack_size orelse 0,46 .stack_size = options.stack_size orelse 0,
50 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,47 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
51 .file = null,48 .file = null,
52 .disable_lld_caching = options.disable_lld_caching,
53 .build_id = options.build_id,49 .build_id = options.build_id,
54 },50 },
55 .llvm_object = llvm_object,
56 };51 };
5752
58 return xcoff;53 return xcoff;
...@@ -70,27 +65,27 @@ pub fn open(...@@ -70,27 +65,27 @@ pub fn open(
70}65}
7166
72pub fn deinit(self: *Xcoff) void {67pub fn deinit(self: *Xcoff) void {
73 self.llvm_object.deinit();68 _ = self;
74}69}
7570
76pub fn updateFunc(71pub fn updateFunc(
77 self: *Xcoff,72 self: *Xcoff,
78 pt: Zcu.PerThread,73 pt: Zcu.PerThread,
79 func_index: InternPool.Index,74 func_index: InternPool.Index,
80 air: Air,75 mir: *const codegen.AnyMir,
81 liveness: Air.Liveness,
82) link.File.UpdateNavError!void {76) link.File.UpdateNavError!void {
83 if (build_options.skip_non_native and builtin.object_format != .xcoff)77 _ = self;
84 @panic("Attempted to compile for object format that was disabled by build configuration");78 _ = pt;
8579 _ = func_index;
86 try self.llvm_object.updateFunc(pt, func_index, air, liveness);80 _ = mir;
81 unreachable; // we always use llvm
87}82}
8883
89pub fn updateNav(self: *Xcoff, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {84pub fn updateNav(self: *Xcoff, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {
90 if (build_options.skip_non_native and builtin.object_format != .xcoff)85 _ = self;
91 @panic("Attempted to compile for object format that was disabled by build configuration");86 _ = pt;
9287 _ = nav;
93 return self.llvm_object.updateNav(pt, nav);88 unreachable; // we always use llvm
94}89}
9590
96pub fn updateExports(91pub fn updateExports(
...@@ -99,21 +94,19 @@ pub fn updateExports(...@@ -99,21 +94,19 @@ pub fn updateExports(
99 exported: Zcu.Exported,94 exported: Zcu.Exported,
100 export_indices: []const Zcu.Export.Index,95 export_indices: []const Zcu.Export.Index,
101) !void {96) !void {
102 if (build_options.skip_non_native and builtin.object_format != .xcoff)97 _ = self;
103 @panic("Attempted to compile for object format that was disabled by build configuration");98 _ = pt;
10499 _ = exported;
105 return self.llvm_object.updateExports(pt, exported, export_indices);100 _ = export_indices;
101 unreachable; // we always use llvm
106}102}
107103
108pub fn flush(self: *Xcoff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {104pub fn flush(self: *Xcoff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
109 return self.flushModule(arena, tid, prog_node);
110}
111
112pub fn flushModule(self: *Xcoff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
113 if (build_options.skip_non_native and builtin.object_format != .xcoff)105 if (build_options.skip_non_native and builtin.object_format != .xcoff)
114 @panic("Attempted to compile for object format that was disabled by build configuration");106 @panic("Attempted to compile for object format that was disabled by build configuration");
115107
108 _ = self;
109 _ = arena;
116 _ = tid;110 _ = tid;
117111 _ = prog_node;
118 try self.base.emitLlvmObject(arena, self.llvm_object, prog_node);
119}112}
src/main.zig+123-258
...@@ -699,55 +699,30 @@ const Emit = union(enum) {...@@ -699,55 +699,30 @@ const Emit = union(enum) {
699 yes_default_path,699 yes_default_path,
700 yes: []const u8,700 yes: []const u8,
701701
702 const Resolved = struct {702 const OutputToCacheReason = enum { listen, @"zig run", @"zig test" };
703 data: ?Compilation.EmitLoc,703 fn resolve(emit: Emit, default_basename: []const u8, output_to_cache: ?OutputToCacheReason) Compilation.CreateOptions.Emit {
704 dir: ?fs.Dir,704 return switch (emit) {
705705 .no => .no,
706 fn deinit(self: *Resolved) void {706 .yes_default_path => if (output_to_cache != null) .yes_cache else .{ .yes_path = default_basename },
707 if (self.dir) |*dir| {707 .yes => |path| if (output_to_cache) |reason| {
708 dir.close();708 switch (reason) {
709 }709 .listen => fatal("--listen incompatible with explicit output path '{s}'", .{path}),
710 }710 .@"zig run", .@"zig test" => fatal(
711 };711 "'{s}' with explicit output path '{s}' requires explicit '-femit-bin=path' or '-fno-emit-bin'",
712712 .{ @tagName(reason), path },
713 fn resolve(emit: Emit, default_basename: []const u8, output_to_cache: bool) !Resolved {713 ),
714 var resolved: Resolved = .{ .data = null, .dir = null };714 }
715 errdefer resolved.deinit();715 } else e: {
716716 // If there's a dirname, check that dir exists. This will give a more descriptive error than `Compilation` otherwise would.
717 switch (emit) {717 if (fs.path.dirname(path)) |dir_path| {
718 .no => {},718 var dir = fs.cwd().openDir(dir_path, .{}) catch |err| {
719 .yes_default_path => {719 fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) });
720 resolved.data = Compilation.EmitLoc{
721 .directory = if (output_to_cache) null else .{
722 .path = null,
723 .handle = fs.cwd(),
724 },
725 .basename = default_basename,
726 };
727 },
728 .yes => |full_path| {
729 const basename = fs.path.basename(full_path);
730 if (fs.path.dirname(full_path)) |dirname| {
731 const handle = try fs.cwd().openDir(dirname, .{});
732 resolved = .{
733 .dir = handle,
734 .data = Compilation.EmitLoc{
735 .basename = basename,
736 .directory = .{
737 .path = dirname,
738 .handle = handle,
739 },
740 },
741 };
742 } else {
743 resolved.data = Compilation.EmitLoc{
744 .basename = basename,
745 .directory = .{ .path = null, .handle = fs.cwd() },
746 };720 };
721 dir.close();
747 }722 }
723 break :e .{ .yes_path = path };
748 },724 },
749 }725 };
750 return resolved;
751 }726 }
752};727};
753728
...@@ -867,9 +842,9 @@ fn buildOutputType(...@@ -867,9 +842,9 @@ fn buildOutputType(
867 var linker_allow_undefined_version: bool = false;842 var linker_allow_undefined_version: bool = false;
868 var linker_enable_new_dtags: ?bool = null;843 var linker_enable_new_dtags: ?bool = null;
869 var disable_c_depfile = false;844 var disable_c_depfile = false;
870 var linker_sort_section: ?link.File.Elf.SortSection = null;845 var linker_sort_section: ?link.File.Lld.Elf.SortSection = null;
871 var linker_gc_sections: ?bool = null;846 var linker_gc_sections: ?bool = null;
872 var linker_compress_debug_sections: ?link.File.Elf.CompressDebugSections = null;847 var linker_compress_debug_sections: ?link.File.Lld.Elf.CompressDebugSections = null;
873 var linker_allow_shlib_undefined: ?bool = null;848 var linker_allow_shlib_undefined: ?bool = null;
874 var allow_so_scripts: bool = false;849 var allow_so_scripts: bool = false;
875 var linker_bind_global_refs_locally: ?bool = null;850 var linker_bind_global_refs_locally: ?bool = null;
...@@ -921,7 +896,7 @@ fn buildOutputType(...@@ -921,7 +896,7 @@ fn buildOutputType(
921 var debug_compiler_runtime_libs = false;896 var debug_compiler_runtime_libs = false;
922 var opt_incremental: ?bool = null;897 var opt_incremental: ?bool = null;
923 var install_name: ?[]const u8 = null;898 var install_name: ?[]const u8 = null;
924 var hash_style: link.File.Elf.HashStyle = .both;899 var hash_style: link.File.Lld.Elf.HashStyle = .both;
925 var entitlements: ?[]const u8 = null;900 var entitlements: ?[]const u8 = null;
926 var pagezero_size: ?u64 = null;901 var pagezero_size: ?u64 = null;
927 var lib_search_strategy: link.UnresolvedInput.SearchStrategy = .paths_first;902 var lib_search_strategy: link.UnresolvedInput.SearchStrategy = .paths_first;
...@@ -1196,11 +1171,11 @@ fn buildOutputType(...@@ -1196,11 +1171,11 @@ fn buildOutputType(
1196 install_name = args_iter.nextOrFatal();1171 install_name = args_iter.nextOrFatal();
1197 } else if (mem.startsWith(u8, arg, "--compress-debug-sections=")) {1172 } else if (mem.startsWith(u8, arg, "--compress-debug-sections=")) {
1198 const param = arg["--compress-debug-sections=".len..];1173 const param = arg["--compress-debug-sections=".len..];
1199 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Elf.CompressDebugSections, param) orelse {1174 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Lld.Elf.CompressDebugSections, param) orelse {
1200 fatal("expected --compress-debug-sections=[none|zlib|zstd], found '{s}'", .{param});1175 fatal("expected --compress-debug-sections=[none|zlib|zstd], found '{s}'", .{param});
1201 };1176 };
1202 } else if (mem.eql(u8, arg, "--compress-debug-sections")) {1177 } else if (mem.eql(u8, arg, "--compress-debug-sections")) {
1203 linker_compress_debug_sections = link.File.Elf.CompressDebugSections.zlib;1178 linker_compress_debug_sections = link.File.Lld.Elf.CompressDebugSections.zlib;
1204 } else if (mem.eql(u8, arg, "-pagezero_size")) {1179 } else if (mem.eql(u8, arg, "-pagezero_size")) {
1205 const next_arg = args_iter.nextOrFatal();1180 const next_arg = args_iter.nextOrFatal();
1206 pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| {1181 pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| {
...@@ -2368,7 +2343,7 @@ fn buildOutputType(...@@ -2368,7 +2343,7 @@ fn buildOutputType(
2368 if (it.only_arg.len == 0) {2343 if (it.only_arg.len == 0) {
2369 linker_compress_debug_sections = .zlib;2344 linker_compress_debug_sections = .zlib;
2370 } else {2345 } else {
2371 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Elf.CompressDebugSections, it.only_arg) orelse {2346 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Lld.Elf.CompressDebugSections, it.only_arg) orelse {
2372 fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{it.only_arg});2347 fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{it.only_arg});
2373 };2348 };
2374 }2349 }
...@@ -2505,7 +2480,7 @@ fn buildOutputType(...@@ -2505,7 +2480,7 @@ fn buildOutputType(
2505 linker_print_map = true;2480 linker_print_map = true;
2506 } else if (mem.eql(u8, arg, "--sort-section")) {2481 } else if (mem.eql(u8, arg, "--sort-section")) {
2507 const arg1 = linker_args_it.nextOrFatal();2482 const arg1 = linker_args_it.nextOrFatal();
2508 linker_sort_section = std.meta.stringToEnum(link.File.Elf.SortSection, arg1) orelse {2483 linker_sort_section = std.meta.stringToEnum(link.File.Lld.Elf.SortSection, arg1) orelse {
2509 fatal("expected [name|alignment] after --sort-section, found '{s}'", .{arg1});2484 fatal("expected [name|alignment] after --sort-section, found '{s}'", .{arg1});
2510 };2485 };
2511 } else if (mem.eql(u8, arg, "--allow-shlib-undefined") or2486 } else if (mem.eql(u8, arg, "--allow-shlib-undefined") or
...@@ -2551,7 +2526,7 @@ fn buildOutputType(...@@ -2551,7 +2526,7 @@ fn buildOutputType(
2551 try linker_export_symbol_names.append(arena, linker_args_it.nextOrFatal());2526 try linker_export_symbol_names.append(arena, linker_args_it.nextOrFatal());
2552 } else if (mem.eql(u8, arg, "--compress-debug-sections")) {2527 } else if (mem.eql(u8, arg, "--compress-debug-sections")) {
2553 const arg1 = linker_args_it.nextOrFatal();2528 const arg1 = linker_args_it.nextOrFatal();
2554 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Elf.CompressDebugSections, arg1) orelse {2529 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Lld.Elf.CompressDebugSections, arg1) orelse {
2555 fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{arg1});2530 fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{arg1});
2556 };2531 };
2557 } else if (mem.startsWith(u8, arg, "-z")) {2532 } else if (mem.startsWith(u8, arg, "-z")) {
...@@ -2764,7 +2739,7 @@ fn buildOutputType(...@@ -2764,7 +2739,7 @@ fn buildOutputType(
2764 mem.eql(u8, arg, "--hash-style"))2739 mem.eql(u8, arg, "--hash-style"))
2765 {2740 {
2766 const next_arg = linker_args_it.nextOrFatal();2741 const next_arg = linker_args_it.nextOrFatal();
2767 hash_style = std.meta.stringToEnum(link.File.Elf.HashStyle, next_arg) orelse {2742 hash_style = std.meta.stringToEnum(link.File.Lld.Elf.HashStyle, next_arg) orelse {
2768 fatal("expected [sysv|gnu|both] after --hash-style, found '{s}'", .{2743 fatal("expected [sysv|gnu|both] after --hash-style, found '{s}'", .{
2769 next_arg,2744 next_arg,
2770 });2745 });
...@@ -2830,7 +2805,7 @@ fn buildOutputType(...@@ -2830,7 +2805,7 @@ fn buildOutputType(
2830 .link => {2805 .link => {
2831 create_module.opts.output_mode = if (is_shared_lib) .Lib else .Exe;2806 create_module.opts.output_mode = if (is_shared_lib) .Lib else .Exe;
2832 if (emit_bin != .no) {2807 if (emit_bin != .no) {
2833 emit_bin = if (out_path) |p| .{ .yes = p } else EmitBin.yes_a_out;2808 emit_bin = if (out_path) |p| .{ .yes = p } else .yes_a_out;
2834 }2809 }
2835 if (emit_llvm) {2810 if (emit_llvm) {
2836 fatal("-emit-llvm cannot be used when linking", .{});2811 fatal("-emit-llvm cannot be used when linking", .{});
...@@ -3208,7 +3183,17 @@ fn buildOutputType(...@@ -3208,7 +3183,17 @@ fn buildOutputType(
3208 var cleanup_emit_bin_dir: ?fs.Dir = null;3183 var cleanup_emit_bin_dir: ?fs.Dir = null;
3209 defer if (cleanup_emit_bin_dir) |*dir| dir.close();3184 defer if (cleanup_emit_bin_dir) |*dir| dir.close();
32103185
3211 const output_to_cache = listen != .none;3186 // For `zig run` and `zig test`, we don't want to put the binary in the cwd by default. So, if
3187 // the binary is requested with no explicit path (as is the default), we emit to the cache.
3188 const output_to_cache: ?Emit.OutputToCacheReason = switch (listen) {
3189 .stdio, .ip4 => .listen,
3190 .none => if (arg_mode == .run and emit_bin == .yes_default_path)
3191 .@"zig run"
3192 else if (arg_mode == .zig_test and emit_bin == .yes_default_path)
3193 .@"zig test"
3194 else
3195 null,
3196 };
3212 const optional_version = if (have_version) version else null;3197 const optional_version = if (have_version) version else null;
32133198
3214 const root_name = if (provided_name) |n| n else main_mod.fully_qualified_name;3199 const root_name = if (provided_name) |n| n else main_mod.fully_qualified_name;
...@@ -3225,150 +3210,57 @@ fn buildOutputType(...@@ -3225,150 +3210,57 @@ fn buildOutputType(
3225 },3210 },
3226 };3211 };
32273212
3228 const a_out_basename = switch (target.ofmt) {3213 const emit_bin_resolved: Compilation.CreateOptions.Emit = switch (emit_bin) {
3229 .coff => "a.exe",3214 .no => .no,
3230 else => "a.out",3215 .yes_default_path => emit: {
3231 };3216 if (output_to_cache != null) break :emit .yes_cache;
32323217 const name = switch (clang_preprocessor_mode) {
3233 const emit_bin_loc: ?Compilation.EmitLoc = switch (emit_bin) {3218 .pch => try std.fmt.allocPrint(arena, "{s}.pch", .{root_name}),
3234 .no => null,3219 else => try std.zig.binNameAlloc(arena, .{
3235 .yes_default_path => Compilation.EmitLoc{
3236 .directory = blk: {
3237 switch (arg_mode) {
3238 .run, .zig_test => break :blk null,
3239 .build, .cc, .cpp, .translate_c, .zig_test_obj => {
3240 if (output_to_cache) {
3241 break :blk null;
3242 } else {
3243 break :blk .{ .path = null, .handle = fs.cwd() };
3244 }
3245 },
3246 }
3247 },
3248 .basename = if (clang_preprocessor_mode == .pch)
3249 try std.fmt.allocPrint(arena, "{s}.pch", .{root_name})
3250 else
3251 try std.zig.binNameAlloc(arena, .{
3252 .root_name = root_name,3220 .root_name = root_name,
3253 .target = target,3221 .target = target,
3254 .output_mode = create_module.resolved_options.output_mode,3222 .output_mode = create_module.resolved_options.output_mode,
3255 .link_mode = create_module.resolved_options.link_mode,3223 .link_mode = create_module.resolved_options.link_mode,
3256 .version = optional_version,3224 .version = optional_version,
3257 }),3225 }),
3226 };
3227 break :emit .{ .yes_path = name };
3258 },3228 },
3259 .yes => |full_path| b: {3229 .yes => |path| if (output_to_cache != null) {
3260 const basename = fs.path.basename(full_path);3230 assert(output_to_cache == .listen); // there was an explicit bin path
3261 if (fs.path.dirname(full_path)) |dirname| {3231 fatal("--listen incompatible with explicit output path '{s}'", .{path});
3262 const handle = fs.cwd().openDir(dirname, .{}) catch |err| {3232 } else emit: {
3263 fatal("unable to open output directory '{s}': {s}", .{ dirname, @errorName(err) });3233 // If there's a dirname, check that dir exists. This will give a more descriptive error than `Compilation` otherwise would.
3264 };3234 if (fs.path.dirname(path)) |dir_path| {
3265 cleanup_emit_bin_dir = handle;3235 var dir = fs.cwd().openDir(dir_path, .{}) catch |err| {
3266 break :b Compilation.EmitLoc{3236 fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) });
3267 .basename = basename,
3268 .directory = .{
3269 .path = dirname,
3270 .handle = handle,
3271 },
3272 };
3273 } else {
3274 break :b Compilation.EmitLoc{
3275 .basename = basename,
3276 .directory = .{ .path = null, .handle = fs.cwd() },
3277 };3237 };
3238 dir.close();
3278 }3239 }
3240 break :emit .{ .yes_path = path };
3279 },3241 },
3280 .yes_a_out => Compilation.EmitLoc{3242 .yes_a_out => emit: {
3281 .directory = .{ .path = null, .handle = fs.cwd() },3243 assert(output_to_cache == null);
3282 .basename = a_out_basename,3244 break :emit .{ .yes_path = switch (target.ofmt) {
3245 .coff => "a.exe",
3246 else => "a.out",
3247 } };
3283 },3248 },
3284 };3249 };
32853250
3286 const default_h_basename = try std.fmt.allocPrint(arena, "{s}.h", .{root_name});3251 const default_h_basename = try std.fmt.allocPrint(arena, "{s}.h", .{root_name});
3287 var emit_h_resolved = emit_h.resolve(default_h_basename, output_to_cache) catch |err| {3252 const emit_h_resolved = emit_h.resolve(default_h_basename, output_to_cache);
3288 switch (emit_h) {
3289 .yes => |p| {
3290 fatal("unable to open directory from argument '-femit-h', '{s}': {s}", .{
3291 p, @errorName(err),
3292 });
3293 },
3294 .yes_default_path => {
3295 fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{
3296 default_h_basename, @errorName(err),
3297 });
3298 },
3299 .no => unreachable,
3300 }
3301 };
3302 defer emit_h_resolved.deinit();
33033253
3304 const default_asm_basename = try std.fmt.allocPrint(arena, "{s}.s", .{root_name});3254 const default_asm_basename = try std.fmt.allocPrint(arena, "{s}.s", .{root_name});
3305 var emit_asm_resolved = emit_asm.resolve(default_asm_basename, output_to_cache) catch |err| {3255 const emit_asm_resolved = emit_asm.resolve(default_asm_basename, output_to_cache);
3306 switch (emit_asm) {
3307 .yes => |p| {
3308 fatal("unable to open directory from argument '-femit-asm', '{s}': {s}", .{
3309 p, @errorName(err),
3310 });
3311 },
3312 .yes_default_path => {
3313 fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{
3314 default_asm_basename, @errorName(err),
3315 });
3316 },
3317 .no => unreachable,
3318 }
3319 };
3320 defer emit_asm_resolved.deinit();
33213256
3322 const default_llvm_ir_basename = try std.fmt.allocPrint(arena, "{s}.ll", .{root_name});3257 const default_llvm_ir_basename = try std.fmt.allocPrint(arena, "{s}.ll", .{root_name});
3323 var emit_llvm_ir_resolved = emit_llvm_ir.resolve(default_llvm_ir_basename, output_to_cache) catch |err| {3258 const emit_llvm_ir_resolved = emit_llvm_ir.resolve(default_llvm_ir_basename, output_to_cache);
3324 switch (emit_llvm_ir) {
3325 .yes => |p| {
3326 fatal("unable to open directory from argument '-femit-llvm-ir', '{s}': {s}", .{
3327 p, @errorName(err),
3328 });
3329 },
3330 .yes_default_path => {
3331 fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{
3332 default_llvm_ir_basename, @errorName(err),
3333 });
3334 },
3335 .no => unreachable,
3336 }
3337 };
3338 defer emit_llvm_ir_resolved.deinit();
33393259
3340 const default_llvm_bc_basename = try std.fmt.allocPrint(arena, "{s}.bc", .{root_name});3260 const default_llvm_bc_basename = try std.fmt.allocPrint(arena, "{s}.bc", .{root_name});
3341 var emit_llvm_bc_resolved = emit_llvm_bc.resolve(default_llvm_bc_basename, output_to_cache) catch |err| {3261 const emit_llvm_bc_resolved = emit_llvm_bc.resolve(default_llvm_bc_basename, output_to_cache);
3342 switch (emit_llvm_bc) {
3343 .yes => |p| {
3344 fatal("unable to open directory from argument '-femit-llvm-bc', '{s}': {s}", .{
3345 p, @errorName(err),
3346 });
3347 },
3348 .yes_default_path => {
3349 fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{
3350 default_llvm_bc_basename, @errorName(err),
3351 });
3352 },
3353 .no => unreachable,
3354 }
3355 };
3356 defer emit_llvm_bc_resolved.deinit();
33573262
3358 var emit_docs_resolved = emit_docs.resolve("docs", output_to_cache) catch |err| {3263 const emit_docs_resolved = emit_docs.resolve("docs", output_to_cache);
3359 switch (emit_docs) {
3360 .yes => |p| {
3361 fatal("unable to open directory from argument '-femit-docs', '{s}': {s}", .{
3362 p, @errorName(err),
3363 });
3364 },
3365 .yes_default_path => {
3366 fatal("unable to open directory 'docs': {s}", .{@errorName(err)});
3367 },
3368 .no => unreachable,
3369 }
3370 };
3371 defer emit_docs_resolved.deinit();
33723264
3373 const is_exe_or_dyn_lib = switch (create_module.resolved_options.output_mode) {3265 const is_exe_or_dyn_lib = switch (create_module.resolved_options.output_mode) {
3374 .Obj => false,3266 .Obj => false,
...@@ -3378,7 +3270,7 @@ fn buildOutputType(...@@ -3378,7 +3270,7 @@ fn buildOutputType(
3378 // Note that cmake when targeting Windows will try to execute3270 // Note that cmake when targeting Windows will try to execute
3379 // zig cc to make an executable and output an implib too.3271 // zig cc to make an executable and output an implib too.
3380 const implib_eligible = is_exe_or_dyn_lib and3272 const implib_eligible = is_exe_or_dyn_lib and
3381 emit_bin_loc != null and target.os.tag == .windows;3273 emit_bin_resolved != .no and target.os.tag == .windows;
3382 if (!implib_eligible) {3274 if (!implib_eligible) {
3383 if (!emit_implib_arg_provided) {3275 if (!emit_implib_arg_provided) {
3384 emit_implib = .no;3276 emit_implib = .no;
...@@ -3387,22 +3279,18 @@ fn buildOutputType(...@@ -3387,22 +3279,18 @@ fn buildOutputType(
3387 }3279 }
3388 }3280 }
3389 const default_implib_basename = try std.fmt.allocPrint(arena, "{s}.lib", .{root_name});3281 const default_implib_basename = try std.fmt.allocPrint(arena, "{s}.lib", .{root_name});
3390 var emit_implib_resolved = switch (emit_implib) {3282 const emit_implib_resolved: Compilation.CreateOptions.Emit = switch (emit_implib) {
3391 .no => Emit.Resolved{ .data = null, .dir = null },3283 .no => .no,
3392 .yes => |p| emit_implib.resolve(default_implib_basename, output_to_cache) catch |err| {3284 .yes => emit_implib.resolve(default_implib_basename, output_to_cache),
3393 fatal("unable to open directory from argument '-femit-implib', '{s}': {s}", .{3285 .yes_default_path => emit: {
3394 p, @errorName(err),3286 if (output_to_cache != null) break :emit .yes_cache;
3287 const p = try fs.path.join(arena, &.{
3288 fs.path.dirname(emit_bin_resolved.yes_path) orelse ".",
3289 default_implib_basename,
3395 });3290 });
3396 },3291 break :emit .{ .yes_path = p };
3397 .yes_default_path => Emit.Resolved{
3398 .data = Compilation.EmitLoc{
3399 .directory = emit_bin_loc.?.directory,
3400 .basename = default_implib_basename,
3401 },
3402 .dir = null,
3403 },3292 },
3404 };3293 };
3405 defer emit_implib_resolved.deinit();
34063294
3407 var thread_pool: ThreadPool = undefined;3295 var thread_pool: ThreadPool = undefined;
3408 try thread_pool.init(.{3296 try thread_pool.init(.{
...@@ -3456,7 +3344,7 @@ fn buildOutputType(...@@ -3456,7 +3344,7 @@ fn buildOutputType(
3456 src.src_path = try dirs.local_cache.join(arena, &.{sub_path});3344 src.src_path = try dirs.local_cache.join(arena, &.{sub_path});
3457 }3345 }
34583346
3459 if (build_options.have_llvm and emit_asm != .no) {3347 if (build_options.have_llvm and emit_asm_resolved != .no) {
3460 // LLVM has no way to set this non-globally.3348 // LLVM has no way to set this non-globally.
3461 const argv = [_][*:0]const u8{ "zig (LLVM option parsing)", "--x86-asm-syntax=intel" };3349 const argv = [_][*:0]const u8{ "zig (LLVM option parsing)", "--x86-asm-syntax=intel" };
3462 @import("codegen/llvm/bindings.zig").ParseCommandLineOptions(argv.len, &argv);3350 @import("codegen/llvm/bindings.zig").ParseCommandLineOptions(argv.len, &argv);
...@@ -3472,23 +3360,11 @@ fn buildOutputType(...@@ -3472,23 +3360,11 @@ fn buildOutputType(
3472 fatal("--debug-incremental requires -fincremental", .{});3360 fatal("--debug-incremental requires -fincremental", .{});
3473 }3361 }
34743362
3475 const disable_lld_caching = !output_to_cache;
3476
3477 const cache_mode: Compilation.CacheMode = b: {3363 const cache_mode: Compilation.CacheMode = b: {
3364 // Once incremental compilation is the default, we'll want some smarter logic here,
3365 // considering things like the backend in use and whether there's a ZCU.
3366 if (output_to_cache == null) break :b .none;
3478 if (incremental) break :b .incremental;3367 if (incremental) break :b .incremental;
3479 if (disable_lld_caching) break :b .incremental;
3480 if (!create_module.resolved_options.have_zcu) break :b .whole;
3481
3482 // TODO: once we support incremental compilation for the LLVM backend
3483 // via saving the LLVM module into a bitcode file and restoring it,
3484 // along with compiler state, this clause can be removed so that
3485 // incremental cache mode is used for LLVM backend too.
3486 if (create_module.resolved_options.use_llvm) break :b .whole;
3487
3488 // Eventually, this default should be `.incremental`. However, since incremental
3489 // compilation is currently an opt-in feature, it makes a strictly worse default cache mode
3490 // than `.whole`.
3491 // https://github.com/ziglang/zig/issues/21165
3492 break :b .whole;3368 break :b .whole;
3493 };3369 };
34943370
...@@ -3510,13 +3386,13 @@ fn buildOutputType(...@@ -3510,13 +3386,13 @@ fn buildOutputType(
3510 .main_mod = main_mod,3386 .main_mod = main_mod,
3511 .root_mod = root_mod,3387 .root_mod = root_mod,
3512 .std_mod = std_mod,3388 .std_mod = std_mod,
3513 .emit_bin = emit_bin_loc,3389 .emit_bin = emit_bin_resolved,
3514 .emit_h = emit_h_resolved.data,3390 .emit_h = emit_h_resolved,
3515 .emit_asm = emit_asm_resolved.data,3391 .emit_asm = emit_asm_resolved,
3516 .emit_llvm_ir = emit_llvm_ir_resolved.data,3392 .emit_llvm_ir = emit_llvm_ir_resolved,
3517 .emit_llvm_bc = emit_llvm_bc_resolved.data,3393 .emit_llvm_bc = emit_llvm_bc_resolved,
3518 .emit_docs = emit_docs_resolved.data,3394 .emit_docs = emit_docs_resolved,
3519 .emit_implib = emit_implib_resolved.data,3395 .emit_implib = emit_implib_resolved,
3520 .lib_directories = create_module.lib_directories.items,3396 .lib_directories = create_module.lib_directories.items,
3521 .rpath_list = create_module.rpath_list.items,3397 .rpath_list = create_module.rpath_list.items,
3522 .symbol_wrap_set = symbol_wrap_set,3398 .symbol_wrap_set = symbol_wrap_set,
...@@ -3599,7 +3475,6 @@ fn buildOutputType(...@@ -3599,7 +3475,6 @@ fn buildOutputType(
3599 .test_filters = test_filters.items,3475 .test_filters = test_filters.items,
3600 .test_name_prefix = test_name_prefix,3476 .test_name_prefix = test_name_prefix,
3601 .test_runner_path = test_runner_path,3477 .test_runner_path = test_runner_path,
3602 .disable_lld_caching = disable_lld_caching,
3603 .cache_mode = cache_mode,3478 .cache_mode = cache_mode,
3604 .subsystem = subsystem,3479 .subsystem = subsystem,
3605 .debug_compile_errors = debug_compile_errors,3480 .debug_compile_errors = debug_compile_errors,
...@@ -3744,13 +3619,8 @@ fn buildOutputType(...@@ -3744,13 +3619,8 @@ fn buildOutputType(
3744 }) {3619 }) {
3745 dev.checkAny(&.{ .run_command, .test_command });3620 dev.checkAny(&.{ .run_command, .test_command });
37463621
3747 if (test_exec_args.items.len == 0 and target.ofmt == .c) default_exec_args: {3622 if (test_exec_args.items.len == 0 and target.ofmt == .c and emit_bin_resolved != .no) {
3748 // Default to using `zig run` to execute the produced .c code from `zig test`.3623 // Default to using `zig run` to execute the produced .c code from `zig test`.
3749 const c_code_loc = emit_bin_loc orelse break :default_exec_args;
3750 const c_code_directory = c_code_loc.directory orelse comp.bin_file.?.emit.root_dir;
3751 const c_code_path = try fs.path.join(arena, &[_][]const u8{
3752 c_code_directory.path orelse ".", c_code_loc.basename,
3753 });
3754 try test_exec_args.appendSlice(arena, &.{ self_exe_path, "run" });3624 try test_exec_args.appendSlice(arena, &.{ self_exe_path, "run" });
3755 if (dirs.zig_lib.path) |p| {3625 if (dirs.zig_lib.path) |p| {
3756 try test_exec_args.appendSlice(arena, &.{ "-I", p });3626 try test_exec_args.appendSlice(arena, &.{ "-I", p });
...@@ -3775,7 +3645,7 @@ fn buildOutputType(...@@ -3775,7 +3645,7 @@ fn buildOutputType(
3775 if (create_module.dynamic_linker) |dl| {3645 if (create_module.dynamic_linker) |dl| {
3776 try test_exec_args.appendSlice(arena, &.{ "--dynamic-linker", dl });3646 try test_exec_args.appendSlice(arena, &.{ "--dynamic-linker", dl });
3777 }3647 }
3778 try test_exec_args.append(arena, c_code_path);3648 try test_exec_args.append(arena, null); // placeholder for the path of the emitted C source file
3779 }3649 }
37803650
3781 try runOrTest(3651 try runOrTest(
...@@ -4354,12 +4224,22 @@ fn runOrTest(...@@ -4354,12 +4224,22 @@ fn runOrTest(
4354 runtime_args_start: ?usize,4224 runtime_args_start: ?usize,
4355 link_libc: bool,4225 link_libc: bool,
4356) !void {4226) !void {
4357 const lf = comp.bin_file orelse return;4227 const raw_emit_bin = comp.emit_bin orelse return;
4358 // A naive `directory.join` here will indeed get the correct path to the binary,4228 const exe_path = switch (comp.cache_use) {
4359 // however, in the case of cwd, we actually want `./foo` so that the path can be executed.4229 .none => p: {
4360 const exe_path = try fs.path.join(arena, &[_][]const u8{4230 if (fs.path.isAbsolute(raw_emit_bin)) break :p raw_emit_bin;
4361 lf.emit.root_dir.path orelse ".", lf.emit.sub_path,4231 // Use `fs.path.join` to make a file in the cwd is still executed properly.
4362 });4232 break :p try fs.path.join(arena, &.{
4233 ".",
4234 raw_emit_bin,
4235 });
4236 },
4237 .whole, .incremental => try comp.dirs.local_cache.join(arena, &.{
4238 "o",
4239 &Cache.binToHex(comp.digest.?),
4240 raw_emit_bin,
4241 }),
4242 };
43634243
4364 var argv = std.ArrayList([]const u8).init(gpa);4244 var argv = std.ArrayList([]const u8).init(gpa);
4365 defer argv.deinit();4245 defer argv.deinit();
...@@ -5087,16 +4967,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -5087,16 +4967,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
5087 };4967 };
5088 };4968 };
50894969
5090 const exe_basename = try std.zig.binNameAlloc(arena, .{
5091 .root_name = "build",
5092 .target = resolved_target.result,
5093 .output_mode = .Exe,
5094 });
5095 const emit_bin: Compilation.EmitLoc = .{
5096 .directory = null, // Use the local zig-cache.
5097 .basename = exe_basename,
5098 };
5099
5100 process.raiseFileDescriptorLimit();4970 process.raiseFileDescriptorLimit();
51014971
5102 const cwd_path = try introspect.getResolvedCwd(arena);4972 const cwd_path = try introspect.getResolvedCwd(arena);
...@@ -5357,8 +5227,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -5357,8 +5227,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
5357 .config = config,5227 .config = config,
5358 .root_mod = root_mod,5228 .root_mod = root_mod,
5359 .main_mod = build_mod,5229 .main_mod = build_mod,
5360 .emit_bin = emit_bin,5230 .emit_bin = .yes_cache,
5361 .emit_h = null,
5362 .self_exe_path = self_exe_path,5231 .self_exe_path = self_exe_path,
5363 .thread_pool = &thread_pool,5232 .thread_pool = &thread_pool,
5364 .verbose_cc = verbose_cc,5233 .verbose_cc = verbose_cc,
...@@ -5386,8 +5255,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -5386,8 +5255,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
5386 // Since incremental compilation isn't done yet, we use cache_mode = whole5255 // Since incremental compilation isn't done yet, we use cache_mode = whole
5387 // above, and thus the output file is already closed.5256 // above, and thus the output file is already closed.
5388 //try comp.makeBinFileExecutable();5257 //try comp.makeBinFileExecutable();
5389 child_argv.items[argv_index_exe] =5258 child_argv.items[argv_index_exe] = try dirs.local_cache.join(arena, &.{
5390 try dirs.local_cache.join(arena, &.{comp.cache_use.whole.bin_sub_path.?});5259 "o",
5260 &Cache.binToHex(comp.digest.?),
5261 comp.emit_bin.?,
5262 });
5391 }5263 }
53925264
5393 if (process.can_spawn) {5265 if (process.can_spawn) {
...@@ -5504,16 +5376,6 @@ fn jitCmd(...@@ -5504,16 +5376,6 @@ fn jitCmd(
5504 .is_explicit_dynamic_linker = false,5376 .is_explicit_dynamic_linker = false,
5505 };5377 };
55065378
5507 const exe_basename = try std.zig.binNameAlloc(arena, .{
5508 .root_name = options.cmd_name,
5509 .target = resolved_target.result,
5510 .output_mode = .Exe,
5511 });
5512 const emit_bin: Compilation.EmitLoc = .{
5513 .directory = null, // Use the global zig-cache.
5514 .basename = exe_basename,
5515 };
5516
5517 const self_exe_path = fs.selfExePathAlloc(arena) catch |err| {5379 const self_exe_path = fs.selfExePathAlloc(arena) catch |err| {
5518 fatal("unable to find self exe path: {s}", .{@errorName(err)});5380 fatal("unable to find self exe path: {s}", .{@errorName(err)});
5519 };5381 };
...@@ -5605,8 +5467,7 @@ fn jitCmd(...@@ -5605,8 +5467,7 @@ fn jitCmd(
5605 .config = config,5467 .config = config,
5606 .root_mod = root_mod,5468 .root_mod = root_mod,
5607 .main_mod = root_mod,5469 .main_mod = root_mod,
5608 .emit_bin = emit_bin,5470 .emit_bin = .yes_cache,
5609 .emit_h = null,
5610 .self_exe_path = self_exe_path,5471 .self_exe_path = self_exe_path,
5611 .thread_pool = &thread_pool,5472 .thread_pool = &thread_pool,
5612 .cache_mode = .whole,5473 .cache_mode = .whole,
...@@ -5637,7 +5498,11 @@ fn jitCmd(...@@ -5637,7 +5498,11 @@ fn jitCmd(
5637 };5498 };
5638 }5499 }
56395500
5640 const exe_path = try dirs.global_cache.join(arena, &.{comp.cache_use.whole.bin_sub_path.?});5501 const exe_path = try dirs.global_cache.join(arena, &.{
5502 "o",
5503 &Cache.binToHex(comp.digest.?),
5504 comp.emit_bin.?,
5505 });
5641 child_argv.appendAssumeCapacity(exe_path);5506 child_argv.appendAssumeCapacity(exe_path);
5642 }5507 }
56435508
src/target.zig+4-2
...@@ -739,7 +739,7 @@ pub fn functionPointerMask(target: std.Target) ?u64 {...@@ -739,7 +739,7 @@ pub fn functionPointerMask(target: std.Target) ?u64 {
739739
740pub fn supportsTailCall(target: std.Target, backend: std.builtin.CompilerBackend) bool {740pub fn supportsTailCall(target: std.Target, backend: std.builtin.CompilerBackend) bool {
741 switch (backend) {741 switch (backend) {
742 .stage1, .stage2_llvm => return @import("codegen/llvm.zig").supportsTailCall(target),742 .stage2_llvm => return @import("codegen/llvm.zig").supportsTailCall(target),
743 .stage2_c => return true,743 .stage2_c => return true,
744 else => return false,744 else => return false,
745 }745 }
...@@ -850,7 +850,9 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt...@@ -850,7 +850,9 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt
850 },850 },
851 .separate_thread => switch (backend) {851 .separate_thread => switch (backend) {
852 .stage2_llvm => false,852 .stage2_llvm => false,
853 else => true,853 .stage2_c, .stage2_wasm, .stage2_x86_64 => true,
854 // TODO: most self-hosted backends should be able to support this without too much work.
855 else => false,
854 },856 },
855 };857 };
856}858}
stage1/wasi.c+12-12
...@@ -517,7 +517,7 @@ uint32_t wasi_snapshot_preview1_fd_read(uint32_t fd, uint32_t iovs, uint32_t iov...@@ -517,7 +517,7 @@ uint32_t wasi_snapshot_preview1_fd_read(uint32_t fd, uint32_t iovs, uint32_t iov
517 case wasi_filetype_character_device: break;517 case wasi_filetype_character_device: break;
518 case wasi_filetype_regular_file: break;518 case wasi_filetype_regular_file: break;
519 case wasi_filetype_directory: return wasi_errno_inval;519 case wasi_filetype_directory: return wasi_errno_inval;
520 default: panic("unimplemented");520 default: panic("unimplemented: fd_read special file");
521 }521 }
522522
523 size_t size = 0;523 size_t size = 0;
...@@ -629,7 +629,7 @@ uint32_t wasi_snapshot_preview1_fd_pwrite(uint32_t fd, uint32_t iovs, uint32_t i...@@ -629,7 +629,7 @@ uint32_t wasi_snapshot_preview1_fd_pwrite(uint32_t fd, uint32_t iovs, uint32_t i
629 case wasi_filetype_character_device: break;629 case wasi_filetype_character_device: break;
630 case wasi_filetype_regular_file: break;630 case wasi_filetype_regular_file: break;
631 case wasi_filetype_directory: return wasi_errno_inval;631 case wasi_filetype_directory: return wasi_errno_inval;
632 default: panic("unimplemented");632 default: panic("unimplemented: fd_pwrite special file");
633 }633 }
634634
635 fpos_t pos;635 fpos_t pos;
...@@ -679,7 +679,7 @@ uint32_t wasi_snapshot_preview1_fd_filestat_set_times(uint32_t fd, uint64_t atim...@@ -679,7 +679,7 @@ uint32_t wasi_snapshot_preview1_fd_filestat_set_times(uint32_t fd, uint64_t atim
679 fprintf(stderr, "wasi_snapshot_preview1_fd_filestat_set_times(%u, %llu, %llu, 0x%X)\n", fd, (unsigned long long)atim, (unsigned long long)mtim, fst_flags);679 fprintf(stderr, "wasi_snapshot_preview1_fd_filestat_set_times(%u, %llu, %llu, 0x%X)\n", fd, (unsigned long long)atim, (unsigned long long)mtim, fst_flags);
680#endif680#endif
681681
682 panic("unimplemented");682 panic("unimplemented: fd_filestat_set_times");
683 return wasi_errno_success;683 return wasi_errno_success;
684}684}
685685
...@@ -703,7 +703,7 @@ uint32_t wasi_snapshot_preview1_environ_get(uint32_t environ, uint32_t environ_b...@@ -703,7 +703,7 @@ uint32_t wasi_snapshot_preview1_environ_get(uint32_t environ, uint32_t environ_b
703 fprintf(stderr, "wasi_snapshot_preview1_environ_get()\n");703 fprintf(stderr, "wasi_snapshot_preview1_environ_get()\n");
704#endif704#endif
705705
706 panic("unimplemented");706 panic("unimplemented: environ_get");
707 return wasi_errno_success;707 return wasi_errno_success;
708}708}
709709
...@@ -757,7 +757,7 @@ uint32_t wasi_snapshot_preview1_fd_readdir(uint32_t fd, uint32_t buf, uint32_t b...@@ -757,7 +757,7 @@ uint32_t wasi_snapshot_preview1_fd_readdir(uint32_t fd, uint32_t buf, uint32_t b
757 fprintf(stderr, "wasi_snapshot_preview1_fd_readdir(%u, 0x%X, %u, %llu)\n", fd, buf, buf_len, (unsigned long long)cookie);757 fprintf(stderr, "wasi_snapshot_preview1_fd_readdir(%u, 0x%X, %u, %llu)\n", fd, buf, buf_len, (unsigned long long)cookie);
758#endif758#endif
759759
760 panic("unimplemented");760 panic("unimplemented: fd_readdir");
761 return wasi_errno_success;761 return wasi_errno_success;
762}762}
763763
...@@ -774,7 +774,7 @@ uint32_t wasi_snapshot_preview1_fd_write(uint32_t fd, uint32_t iovs, uint32_t io...@@ -774,7 +774,7 @@ uint32_t wasi_snapshot_preview1_fd_write(uint32_t fd, uint32_t iovs, uint32_t io
774 case wasi_filetype_character_device: break;774 case wasi_filetype_character_device: break;
775 case wasi_filetype_regular_file: break;775 case wasi_filetype_regular_file: break;
776 case wasi_filetype_directory: return wasi_errno_inval;776 case wasi_filetype_directory: return wasi_errno_inval;
777 default: panic("unimplemented");777 default: panic("unimplemented: fd_write special file");
778 }778 }
779779
780 size_t size = 0;780 size_t size = 0;
...@@ -825,7 +825,7 @@ uint32_t wasi_snapshot_preview1_path_open(uint32_t fd, uint32_t dirflags, uint32...@@ -825,7 +825,7 @@ uint32_t wasi_snapshot_preview1_path_open(uint32_t fd, uint32_t dirflags, uint32
825 fds[fd_len].fdflags = fdflags;825 fds[fd_len].fdflags = fdflags;
826 switch (des[de].filetype) {826 switch (des[de].filetype) {
827 case wasi_filetype_directory: fds[fd_len].stream = NULL; break;827 case wasi_filetype_directory: fds[fd_len].stream = NULL; break;
828 default: panic("unimplemented");828 default: panic("unimplemented: path_open non-directory DirEntry");
829 }829 }
830 fds[fd_len].fs_rights_inheriting = fs_rights_inheriting;830 fds[fd_len].fs_rights_inheriting = fs_rights_inheriting;
831831
...@@ -943,7 +943,7 @@ uint32_t wasi_snapshot_preview1_path_unlink_file(uint32_t fd, uint32_t path, uin...@@ -943,7 +943,7 @@ uint32_t wasi_snapshot_preview1_path_unlink_file(uint32_t fd, uint32_t path, uin
943 enum wasi_errno lookup_errno = DirEntry_lookup(fd, 0, path_ptr, path_len, &de);943 enum wasi_errno lookup_errno = DirEntry_lookup(fd, 0, path_ptr, path_len, &de);
944 if (lookup_errno != wasi_errno_success) return lookup_errno;944 if (lookup_errno != wasi_errno_success) return lookup_errno;
945 if (des[de].filetype == wasi_filetype_directory) return wasi_errno_isdir;945 if (des[de].filetype == wasi_filetype_directory) return wasi_errno_isdir;
946 if (des[de].filetype != wasi_filetype_regular_file) panic("unimplemented");946 if (des[de].filetype != wasi_filetype_regular_file) panic("unimplemented: path_unlink_file special file");
947 DirEntry_unlink(de);947 DirEntry_unlink(de);
948 return wasi_errno_success;948 return wasi_errno_success;
949}949}
...@@ -961,7 +961,7 @@ uint32_t wasi_snapshot_preview1_fd_pread(uint32_t fd, uint32_t iovs, uint32_t io...@@ -961,7 +961,7 @@ uint32_t wasi_snapshot_preview1_fd_pread(uint32_t fd, uint32_t iovs, uint32_t io
961 case wasi_filetype_character_device: break;961 case wasi_filetype_character_device: break;
962 case wasi_filetype_regular_file: break;962 case wasi_filetype_regular_file: break;
963 case wasi_filetype_directory: return wasi_errno_inval;963 case wasi_filetype_directory: return wasi_errno_inval;
964 default: panic("unimplemented");964 default: panic("unimplemented: fd_pread special file");
965 }965 }
966966
967 fpos_t pos;967 fpos_t pos;
...@@ -975,7 +975,7 @@ uint32_t wasi_snapshot_preview1_fd_pread(uint32_t fd, uint32_t iovs, uint32_t io...@@ -975,7 +975,7 @@ uint32_t wasi_snapshot_preview1_fd_pread(uint32_t fd, uint32_t iovs, uint32_t io
975 if (fds[fd].stream != NULL)975 if (fds[fd].stream != NULL)
976 read_size = fread(&m[load32_align2(&iovs_ptr[i].ptr)], 1, len, fds[fd].stream);976 read_size = fread(&m[load32_align2(&iovs_ptr[i].ptr)], 1, len, fds[fd].stream);
977 else977 else
978 panic("unimplemented");978 panic("unimplemented: fd_pread stream=NULL");
979 size += read_size;979 size += read_size;
980 if (read_size < len) break;980 if (read_size < len) break;
981 }981 }
...@@ -1000,7 +1000,7 @@ uint32_t wasi_snapshot_preview1_fd_seek(uint32_t fd, uint64_t in_offset, uint32_...@@ -1000,7 +1000,7 @@ uint32_t wasi_snapshot_preview1_fd_seek(uint32_t fd, uint64_t in_offset, uint32_
1000 case wasi_filetype_character_device: break;1000 case wasi_filetype_character_device: break;
1001 case wasi_filetype_regular_file: break;1001 case wasi_filetype_regular_file: break;
1002 case wasi_filetype_directory: return wasi_errno_inval;1002 case wasi_filetype_directory: return wasi_errno_inval;
1003 default: panic("unimplemented");1003 default: panic("unimplemented: fd_seek special file");
1004 }1004 }
10051005
1006 if (fds[fd].stream == NULL) return wasi_errno_success;1006 if (fds[fd].stream == NULL) return wasi_errno_success;
...@@ -1035,7 +1035,7 @@ uint32_t wasi_snapshot_preview1_poll_oneoff(uint32_t in, uint32_t out, uint32_t...@@ -1035,7 +1035,7 @@ uint32_t wasi_snapshot_preview1_poll_oneoff(uint32_t in, uint32_t out, uint32_t
1035 fprintf(stderr, "wasi_snapshot_preview1_poll_oneoff(%u)\n", nsubscriptions);1035 fprintf(stderr, "wasi_snapshot_preview1_poll_oneoff(%u)\n", nsubscriptions);
1036#endif1036#endif
10371037
1038 panic("unimplemented");1038 panic("unimplemented: poll_oneoff");
1039 return wasi_errno_success;1039 return wasi_errno_success;
1040}1040}
10411041
test/link/macho.zig+2-2
...@@ -211,7 +211,7 @@ fn testDuplicateDefinitions(b: *Build, opts: Options) *Step {...@@ -211,7 +211,7 @@ fn testDuplicateDefinitions(b: *Build, opts: Options) *Step {
211 expectLinkErrors(exe, test_step, .{ .exact = &.{211 expectLinkErrors(exe, test_step, .{ .exact = &.{
212 "error: duplicate symbol definition: _strong",212 "error: duplicate symbol definition: _strong",
213 "note: defined by /?/a.o",213 "note: defined by /?/a.o",
214 "note: defined by /?/main.o",214 "note: defined by /?/main_zcu.o",
215 } });215 } });
216216
217 return test_step;217 return test_step;
...@@ -2648,7 +2648,7 @@ fn testUnresolvedError(b: *Build, opts: Options) *Step {...@@ -2648,7 +2648,7 @@ fn testUnresolvedError(b: *Build, opts: Options) *Step {
2648 expectLinkErrors(exe, test_step, .{ .exact = &.{2648 expectLinkErrors(exe, test_step, .{ .exact = &.{
2649 "error: undefined symbol: _foo",2649 "error: undefined symbol: _foo",
2650 "note: referenced by /?/a.o:_bar",2650 "note: referenced by /?/a.o:_bar",
2651 "note: referenced by /?/main.o:_main.main",2651 "note: referenced by /?/main_zcu.o:_main.main",
2652 } });2652 } });
2653 } else {2653 } else {
2654 expectLinkErrors(exe, test_step, .{ .exact = &.{2654 expectLinkErrors(exe, test_step, .{ .exact = &.{
test/src/check-stack-trace.zig+1-1
...@@ -65,7 +65,7 @@ pub fn main() !void {...@@ -65,7 +65,7 @@ pub fn main() !void {
65 // This actually violates the DWARF specification (DWARF5 § 3.1.1, lines 24-27).65 // This actually violates the DWARF specification (DWARF5 § 3.1.1, lines 24-27).
66 // The self-hosted backend uses the root Zig source file of the module (in compilance with the spec).66 // The self-hosted backend uses the root Zig source file of the module (in compilance with the spec).
67 if (std.mem.eql(u8, file_name, "test") or67 if (std.mem.eql(u8, file_name, "test") or
68 std.mem.eql(u8, file_name, "test.exe.obj") or68 std.mem.eql(u8, file_name, "test_zcu.obj") or
69 std.mem.endsWith(u8, file_name, ".zig"))69 std.mem.endsWith(u8, file_name, ".zig"))
70 {70 {
71 try buf.appendSlice("[main_file]");71 try buf.appendSlice("[main_file]");
tools/incr-check.zig+1-1
...@@ -314,7 +314,7 @@ const Eval = struct {...@@ -314,7 +314,7 @@ const Eval = struct {
314 const digest = body[@sizeOf(EbpHdr)..][0..Cache.bin_digest_len];314 const digest = body[@sizeOf(EbpHdr)..][0..Cache.bin_digest_len];
315 const result_dir = ".local-cache" ++ std.fs.path.sep_str ++ "o" ++ std.fs.path.sep_str ++ Cache.binToHex(digest.*);315 const result_dir = ".local-cache" ++ std.fs.path.sep_str ++ "o" ++ std.fs.path.sep_str ++ Cache.binToHex(digest.*);
316316
317 const bin_name = try std.zig.binNameAlloc(arena, .{317 const bin_name = try std.zig.EmitArtifact.bin.cacheName(arena, .{
318 .root_name = "root", // corresponds to the module name "root"318 .root_name = "root", // corresponds to the module name "root"
319 .target = eval.target.resolved,319 .target = eval.target.resolved,
320 .output_mode = .Exe,320 .output_mode = .Exe,