| author | |
| committer | |
| log | e5d5a8bc4ea6b27dc3540ad4800a1231ff50b33d |
| tree | 114481f7bbf4d5e6a4703a7606f654dabb5df330 |
| parent | ac1a975f9b5a7d939663fa90556a2f038250c531 |
33 files changed, 476 insertions(+), 199 deletions(-)
lib/std/Thread/Condition.zig+3-3| ... | @@ -161,17 +161,17 @@ const WindowsImpl = struct { | ... | @@ -161,17 +161,17 @@ const WindowsImpl = struct { |
| 161 | } | 161 | } |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | if (comptime builtin.mode == .Debug) { | 164 | if (builtin.mode == .Debug) { |
| 165 | // The internal state of the DebugMutex needs to be handled here as well. | 165 | // The internal state of the DebugMutex needs to be handled here as well. |
| 166 | mutex.impl.locking_thread.store(0, .unordered); | 166 | mutex.impl.locking_thread.store(0, .unordered); |
| 167 | } | 167 | } |
| 168 | const rc = os.windows.kernel32.SleepConditionVariableSRW( | 168 | const rc = os.windows.kernel32.SleepConditionVariableSRW( |
| 169 | &self.condition, | 169 | &self.condition, |
| 170 | if (comptime builtin.mode == .Debug) &mutex.impl.impl.srwlock else &mutex.impl.srwlock, | 170 | if (builtin.mode == .Debug) &mutex.impl.impl.srwlock else &mutex.impl.srwlock, |
| 171 | timeout_ms, | 171 | timeout_ms, |
| 172 | 0, // the srwlock was assumed to acquired in exclusive mode not shared | 172 | 0, // the srwlock was assumed to acquired in exclusive mode not shared |
| 173 | ); | 173 | ); |
| 174 | if (comptime builtin.mode == .Debug) { | 174 | if (builtin.mode == .Debug) { |
| 175 | // The internal state of the DebugMutex needs to be handled here as well. | 175 | // The internal state of the DebugMutex needs to be handled here as well. |
| 176 | mutex.impl.locking_thread.store(std.Thread.getCurrentId(), .unordered); | 176 | mutex.impl.locking_thread.store(std.Thread.getCurrentId(), .unordered); |
| 177 | } | 177 | } |
lib/std/Thread/Mutex.zig+1-1| ... | @@ -158,7 +158,7 @@ const FutexImpl = struct { | ... | @@ -158,7 +158,7 @@ const FutexImpl = struct { |
| 158 | // On x86, use `lock bts` instead of `lock cmpxchg` as: | 158 | // On x86, use `lock bts` instead of `lock cmpxchg` as: |
| 159 | // - they both seem to mark the cache-line as modified regardless: https://stackoverflow.com/a/63350048 | 159 | // - they both seem to mark the cache-line as modified regardless: https://stackoverflow.com/a/63350048 |
| 160 | // - `lock bts` is smaller instruction-wise which makes it better for inlining | 160 | // - `lock bts` is smaller instruction-wise which makes it better for inlining |
| 161 | if (comptime builtin.target.cpu.arch.isX86()) { | 161 | if (builtin.target.cpu.arch.isX86()) { |
| 162 | const locked_bit = @ctz(locked); | 162 | const locked_bit = @ctz(locked); |
| 163 | return self.state.bitSet(locked_bit, .acquire) == 0; | 163 | return self.state.bitSet(locked_bit, .acquire) == 0; |
| 164 | } | 164 | } |
lib/std/debug.zig+3-3| ... | @@ -179,7 +179,7 @@ pub fn dumpHexFallible(bytes: []const u8) !void { | ... | @@ -179,7 +179,7 @@ pub fn dumpHexFallible(bytes: []const u8) !void { |
| 179 | /// TODO multithreaded awareness | 179 | /// TODO multithreaded awareness |
| 180 | pub fn dumpCurrentStackTrace(start_addr: ?usize) void { | 180 | pub fn dumpCurrentStackTrace(start_addr: ?usize) void { |
| 181 | nosuspend { | 181 | nosuspend { |
| 182 | if (comptime builtin.target.isWasm()) { | 182 | if (builtin.target.isWasm()) { |
| 183 | if (native_os == .wasi) { | 183 | if (native_os == .wasi) { |
| 184 | const stderr = io.getStdErr().writer(); | 184 | const stderr = io.getStdErr().writer(); |
| 185 | stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return; | 185 | stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return; |
| ... | @@ -267,7 +267,7 @@ pub inline fn getContext(context: *ThreadContext) bool { | ... | @@ -267,7 +267,7 @@ pub inline fn getContext(context: *ThreadContext) bool { |
| 267 | /// TODO multithreaded awareness | 267 | /// TODO multithreaded awareness |
| 268 | pub fn dumpStackTraceFromBase(context: *ThreadContext) void { | 268 | pub fn dumpStackTraceFromBase(context: *ThreadContext) void { |
| 269 | nosuspend { | 269 | nosuspend { |
| 270 | if (comptime builtin.target.isWasm()) { | 270 | if (builtin.target.isWasm()) { |
| 271 | if (native_os == .wasi) { | 271 | if (native_os == .wasi) { |
| 272 | const stderr = io.getStdErr().writer(); | 272 | const stderr = io.getStdErr().writer(); |
| 273 | stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return; | 273 | stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return; |
| ... | @@ -365,7 +365,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackT | ... | @@ -365,7 +365,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackT |
| 365 | /// TODO multithreaded awareness | 365 | /// TODO multithreaded awareness |
| 366 | pub fn dumpStackTrace(stack_trace: std.builtin.StackTrace) void { | 366 | pub fn dumpStackTrace(stack_trace: std.builtin.StackTrace) void { |
| 367 | nosuspend { | 367 | nosuspend { |
| 368 | if (comptime builtin.target.isWasm()) { | 368 | if (builtin.target.isWasm()) { |
| 369 | if (native_os == .wasi) { | 369 | if (native_os == .wasi) { |
| 370 | const stderr = io.getStdErr().writer(); | 370 | const stderr = io.getStdErr().writer(); |
| 371 | stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return; | 371 | stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return; |
lib/std/debug/SelfInfo.zig+4-4| ... | @@ -121,13 +121,13 @@ pub fn deinit(self: *SelfInfo) void { | ... | @@ -121,13 +121,13 @@ pub fn deinit(self: *SelfInfo) void { |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | pub fn getModuleForAddress(self: *SelfInfo, address: usize) !*Module { | 123 | pub fn getModuleForAddress(self: *SelfInfo, address: usize) !*Module { |
| 124 | if (comptime builtin.target.isDarwin()) { | 124 | if (builtin.target.isDarwin()) { |
| 125 | return self.lookupModuleDyld(address); | 125 | return self.lookupModuleDyld(address); |
| 126 | } else if (native_os == .windows) { | 126 | } else if (native_os == .windows) { |
| 127 | return self.lookupModuleWin32(address); | 127 | return self.lookupModuleWin32(address); |
| 128 | } else if (native_os == .haiku) { | 128 | } else if (native_os == .haiku) { |
| 129 | return self.lookupModuleHaiku(address); | 129 | return self.lookupModuleHaiku(address); |
| 130 | } else if (comptime builtin.target.isWasm()) { | 130 | } else if (builtin.target.isWasm()) { |
| 131 | return self.lookupModuleWasm(address); | 131 | return self.lookupModuleWasm(address); |
| 132 | } else { | 132 | } else { |
| 133 | return self.lookupModuleDl(address); | 133 | return self.lookupModuleDl(address); |
| ... | @@ -138,13 +138,13 @@ pub fn getModuleForAddress(self: *SelfInfo, address: usize) !*Module { | ... | @@ -138,13 +138,13 @@ pub fn getModuleForAddress(self: *SelfInfo, address: usize) !*Module { |
| 138 | // This can be called when getModuleForAddress fails, so implementations should provide | 138 | // This can be called when getModuleForAddress fails, so implementations should provide |
| 139 | // a path that doesn't rely on any side-effects of a prior successful module lookup. | 139 | // a path that doesn't rely on any side-effects of a prior successful module lookup. |
| 140 | pub fn getModuleNameForAddress(self: *SelfInfo, address: usize) ?[]const u8 { | 140 | pub fn getModuleNameForAddress(self: *SelfInfo, address: usize) ?[]const u8 { |
| 141 | if (comptime builtin.target.isDarwin()) { | 141 | if (builtin.target.isDarwin()) { |
| 142 | return self.lookupModuleNameDyld(address); | 142 | return self.lookupModuleNameDyld(address); |
| 143 | } else if (native_os == .windows) { | 143 | } else if (native_os == .windows) { |
| 144 | return self.lookupModuleNameWin32(address); | 144 | return self.lookupModuleNameWin32(address); |
| 145 | } else if (native_os == .haiku) { | 145 | } else if (native_os == .haiku) { |
| 146 | return null; | 146 | return null; |
| 147 | } else if (comptime builtin.target.isWasm()) { | 147 | } else if (builtin.target.isWasm()) { |
| 148 | return null; | 148 | return null; |
| 149 | } else { | 149 | } else { |
| 150 | return self.lookupModuleNameDl(address); | 150 | return self.lookupModuleNameDl(address); |
lib/std/heap.zig+1-1| ... | @@ -890,7 +890,7 @@ test { | ... | @@ -890,7 +890,7 @@ test { |
| 890 | _ = @import("heap/memory_pool.zig"); | 890 | _ = @import("heap/memory_pool.zig"); |
| 891 | _ = ArenaAllocator; | 891 | _ = ArenaAllocator; |
| 892 | _ = GeneralPurposeAllocator; | 892 | _ = GeneralPurposeAllocator; |
| 893 | if (comptime builtin.target.isWasm()) { | 893 | if (builtin.target.isWasm()) { |
| 894 | _ = WasmAllocator; | 894 | _ = WasmAllocator; |
| 895 | _ = WasmPageAllocator; | 895 | _ = WasmPageAllocator; |
| 896 | } | 896 | } |
lib/std/math/big/int.zig+1-1| ... | @@ -2523,7 +2523,7 @@ pub const Const = struct { | ... | @@ -2523,7 +2523,7 @@ pub const Const = struct { |
| 2523 | /// Returns the number of leading zeros in twos-complement form. | 2523 | /// Returns the number of leading zeros in twos-complement form. |
| 2524 | pub fn clz(a: Const, bits: Limb) Limb { | 2524 | pub fn clz(a: Const, bits: Limb) Limb { |
| 2525 | // Limbs are stored in little-endian order but we need to iterate big-endian. | 2525 | // Limbs are stored in little-endian order but we need to iterate big-endian. |
| 2526 | if (!a.positive) return 0; | 2526 | if (!a.positive and !a.eqlZero()) return 0; |
| 2527 | var total_limb_lz: Limb = 0; | 2527 | var total_limb_lz: Limb = 0; |
| 2528 | var i: usize = a.limbs.len; | 2528 | var i: usize = a.limbs.len; |
| 2529 | const bits_per_limb = @bitSizeOf(Limb); | 2529 | const bits_per_limb = @bitSizeOf(Limb); |
lib/std/os.zig+1-1| ... | @@ -157,7 +157,7 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix. | ... | @@ -157,7 +157,7 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix. |
| 157 | return target; | 157 | return target; |
| 158 | }, | 158 | }, |
| 159 | .freebsd => { | 159 | .freebsd => { |
| 160 | if (comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) { | 160 | if (builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) { |
| 161 | var kfile: std.c.kinfo_file = undefined; | 161 | var kfile: std.c.kinfo_file = undefined; |
| 162 | kfile.structsize = std.c.KINFO_FILE_SIZE; | 162 | kfile.structsize = std.c.KINFO_FILE_SIZE; |
| 163 | switch (posix.errno(std.c.fcntl(fd, std.c.F.KINFO, @intFromPtr(&kfile)))) { | 163 | switch (posix.errno(std.c.fcntl(fd, std.c.F.KINFO, @intFromPtr(&kfile)))) { |
lib/std/os/windows.zig+1-1| ... | @@ -1061,7 +1061,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil | ... | @@ -1061,7 +1061,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil |
| 1061 | // us INVALID_PARAMETER. | 1061 | // us INVALID_PARAMETER. |
| 1062 | // The same reasoning for win10_rs5 as in os.renameatW() applies (FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE requires >= win10_rs5). | 1062 | // The same reasoning for win10_rs5 as in os.renameatW() applies (FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE requires >= win10_rs5). |
| 1063 | var need_fallback = true; | 1063 | var need_fallback = true; |
| 1064 | if (comptime builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs5)) { | 1064 | if (builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs5)) { |
| 1065 | // Deletion with posix semantics if the filesystem supports it. | 1065 | // Deletion with posix semantics if the filesystem supports it. |
| 1066 | var info = FILE_DISPOSITION_INFORMATION_EX{ | 1066 | var info = FILE_DISPOSITION_INFORMATION_EX{ |
| 1067 | .Flags = FILE_DISPOSITION_DELETE | | 1067 | .Flags = FILE_DISPOSITION_DELETE | |
lib/std/posix.zig+1-1| ... | @@ -6819,7 +6819,7 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t { | ... | @@ -6819,7 +6819,7 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t { |
| 6819 | } | 6819 | } |
| 6820 | }, | 6820 | }, |
| 6821 | .freebsd => { | 6821 | .freebsd => { |
| 6822 | if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0, .patch = 0 }) == .lt) | 6822 | if (builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0, .patch = 0 }) == .lt) |
| 6823 | @compileError("memfd_create is unavailable on FreeBSD < 13.0"); | 6823 | @compileError("memfd_create is unavailable on FreeBSD < 13.0"); |
| 6824 | const rc = system.memfd_create(name, flags); | 6824 | const rc = system.memfd_create(name, flags); |
| 6825 | switch (errno(rc)) { | 6825 | switch (errno(rc)) { |
lib/std/posix/test.zig+1-1| ... | @@ -804,7 +804,7 @@ test "getrlimit and setrlimit" { | ... | @@ -804,7 +804,7 @@ test "getrlimit and setrlimit" { |
| 804 | // | 804 | // |
| 805 | // This happens for example if RLIMIT_MEMLOCK is bigger than ~2GiB. | 805 | // This happens for example if RLIMIT_MEMLOCK is bigger than ~2GiB. |
| 806 | // In that case the following the limit would be RLIM_INFINITY and the following setrlimit fails with EPERM. | 806 | // In that case the following the limit would be RLIM_INFINITY and the following setrlimit fails with EPERM. |
| 807 | if (comptime builtin.cpu.arch.isMIPS() and builtin.link_libc) { | 807 | if (builtin.cpu.arch.isMIPS() and builtin.link_libc) { |
| 808 | if (limit.cur != linux.RLIM.INFINITY) { | 808 | if (limit.cur != linux.RLIM.INFINITY) { |
| 809 | try posix.setrlimit(resource, limit); | 809 | try posix.setrlimit(resource, limit); |
| 810 | } | 810 | } |
lib/std/simd.zig+4-6| ... | @@ -163,7 +163,7 @@ pub fn interlace(vecs: anytype) @Vector(vectorLength(@TypeOf(vecs[0])) * vecs.le | ... | @@ -163,7 +163,7 @@ pub fn interlace(vecs: anytype) @Vector(vectorLength(@TypeOf(vecs[0])) * vecs.le |
| 163 | // The indices are correct. The problem seems to be with the @shuffle builtin. | 163 | // The indices are correct. The problem seems to be with the @shuffle builtin. |
| 164 | // On MIPS, the test that interlaces small_base gives { 0, 2, 0, 0, 64, 255, 248, 200, 0, 0 }. | 164 | // On MIPS, the test that interlaces small_base gives { 0, 2, 0, 0, 64, 255, 248, 200, 0, 0 }. |
| 165 | // Calling this with two inputs seems to work fine, but I'll let the compile error trigger for all inputs, just to be safe. | 165 | // Calling this with two inputs seems to work fine, but I'll let the compile error trigger for all inputs, just to be safe. |
| 166 | comptime if (builtin.cpu.arch.isMIPS()) @compileError("TODO: Find out why interlace() doesn't work on MIPS"); | 166 | if (builtin.cpu.arch.isMIPS()) @compileError("TODO: Find out why interlace() doesn't work on MIPS"); |
| 167 | 167 | ||
| 168 | const VecType = @TypeOf(vecs[0]); | 168 | const VecType = @TypeOf(vecs[0]); |
| 169 | const vecs_arr = @as([vecs.len]VecType, vecs); | 169 | const vecs_arr = @as([vecs.len]VecType, vecs); |
| ... | @@ -248,7 +248,7 @@ test "vector patterns" { | ... | @@ -248,7 +248,7 @@ test "vector patterns" { |
| 248 | try std.testing.expectEqual([8]u32{ 10, 20, 30, 40, 55, 66, 77, 88 }, join(base, other_base)); | 248 | try std.testing.expectEqual([8]u32{ 10, 20, 30, 40, 55, 66, 77, 88 }, join(base, other_base)); |
| 249 | try std.testing.expectEqual([2]u32{ 20, 30 }, extract(base, 1, 2)); | 249 | try std.testing.expectEqual([2]u32{ 20, 30 }, extract(base, 1, 2)); |
| 250 | 250 | ||
| 251 | if (comptime !builtin.cpu.arch.isMIPS()) { | 251 | if (!builtin.cpu.arch.isMIPS()) { |
| 252 | try std.testing.expectEqual([8]u32{ 10, 55, 20, 66, 30, 77, 40, 88 }, interlace(.{ base, other_base })); | 252 | try std.testing.expectEqual([8]u32{ 10, 55, 20, 66, 30, 77, 40, 88 }, interlace(.{ base, other_base })); |
| 253 | 253 | ||
| 254 | const small_braid = interlace(small_bases); | 254 | const small_braid = interlace(small_bases); |
| ... | @@ -390,7 +390,7 @@ pub fn prefixScanWithFunc( | ... | @@ -390,7 +390,7 @@ pub fn prefixScanWithFunc( |
| 390 | comptime identity: std.meta.Child(@TypeOf(vec)), | 390 | comptime identity: std.meta.Child(@TypeOf(vec)), |
| 391 | ) if (ErrorType == void) @TypeOf(vec) else ErrorType!@TypeOf(vec) { | 391 | ) if (ErrorType == void) @TypeOf(vec) else ErrorType!@TypeOf(vec) { |
| 392 | // I haven't debugged this, but it might be a cousin of sorts to what's going on with interlace. | 392 | // I haven't debugged this, but it might be a cousin of sorts to what's going on with interlace. |
| 393 | comptime if (builtin.cpu.arch.isMIPS()) @compileError("TODO: Find out why prefixScan doesn't work on MIPS"); | 393 | if (builtin.cpu.arch.isMIPS()) @compileError("TODO: Find out why prefixScan doesn't work on MIPS"); |
| 394 | 394 | ||
| 395 | const len = vectorLength(@TypeOf(vec)); | 395 | const len = vectorLength(@TypeOf(vec)); |
| 396 | 396 | ||
| ... | @@ -465,9 +465,7 @@ test "vector prefix scan" { | ... | @@ -465,9 +465,7 @@ test "vector prefix scan" { |
| 465 | if ((builtin.cpu.arch == .armeb or builtin.cpu.arch == .thumbeb) and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/22060 | 465 | if ((builtin.cpu.arch == .armeb or builtin.cpu.arch == .thumbeb) and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/22060 |
| 466 | if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21893 | 466 | if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21893 |
| 467 | 467 | ||
| 468 | if (comptime builtin.cpu.arch.isMIPS()) { | 468 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 469 | return error.SkipZigTest; | ||
| 470 | } | ||
| 471 | 469 | ||
| 472 | const int_base = @Vector(4, i32){ 11, 23, 9, -21 }; | 470 | const int_base = @Vector(4, i32){ 11, 23, 9, -21 }; |
| 473 | const float_base = @Vector(4, f32){ 2, 0.5, -10, 6.54321 }; | 471 | const float_base = @Vector(4, f32){ 2, 0.5, -10, 6.54321 }; |
lib/std/zig/system/NativePaths.zig+1-1| ... | @@ -83,7 +83,7 @@ pub fn detect(arena: Allocator, native_target: std.Target) !NativePaths { | ... | @@ -83,7 +83,7 @@ pub fn detect(arena: Allocator, native_target: std.Target) !NativePaths { |
| 83 | 83 | ||
| 84 | // TODO: consider also adding homebrew paths | 84 | // TODO: consider also adding homebrew paths |
| 85 | // TODO: consider also adding macports paths | 85 | // TODO: consider also adding macports paths |
| 86 | if (comptime builtin.target.isDarwin()) { | 86 | if (builtin.target.isDarwin()) { |
| 87 | if (std.zig.system.darwin.isSdkInstalled(arena)) sdk: { | 87 | if (std.zig.system.darwin.isSdkInstalled(arena)) sdk: { |
| 88 | const sdk = std.zig.system.darwin.getSdk(arena, native_target) orelse break :sdk; | 88 | const sdk = std.zig.system.darwin.getSdk(arena, native_target) orelse break :sdk; |
| 89 | try self.addLibDir(try std.fs.path.join(arena, &.{ sdk, "usr/lib" })); | 89 | try self.addLibDir(try std.fs.path.join(arena, &.{ sdk, "usr/lib" })); |
src/Liveness.zig+6-13| ... | @@ -719,32 +719,25 @@ pub const SwitchBrTable = struct { | ... | @@ -719,32 +719,25 @@ pub const SwitchBrTable = struct { |
| 719 | 719 | ||
| 720 | /// Caller owns the memory. | 720 | /// Caller owns the memory. |
| 721 | pub fn getSwitchBr(l: Liveness, gpa: Allocator, inst: Air.Inst.Index, cases_len: u32) Allocator.Error!SwitchBrTable { | 721 | pub fn getSwitchBr(l: Liveness, gpa: Allocator, inst: Air.Inst.Index, cases_len: u32) Allocator.Error!SwitchBrTable { |
| 722 | var index: usize = l.special.get(inst) orelse return SwitchBrTable{ | 722 | var index: usize = l.special.get(inst) orelse return .{ .deaths = &.{} }; |
| 723 | .deaths = &.{}, | ||
| 724 | }; | ||
| 725 | const else_death_count = l.extra[index]; | 723 | const else_death_count = l.extra[index]; |
| 726 | index += 1; | 724 | index += 1; |
| 727 | 725 | ||
| 728 | var deaths = std.ArrayList([]const Air.Inst.Index).init(gpa); | 726 | var deaths = try gpa.alloc([]const Air.Inst.Index, cases_len); |
| 729 | defer deaths.deinit(); | 727 | errdefer gpa.free(deaths); |
| 730 | try deaths.ensureTotalCapacity(cases_len + 1); | ||
| 731 | 728 | ||
| 732 | var case_i: u32 = 0; | 729 | var case_i: u32 = 0; |
| 733 | while (case_i < cases_len - 1) : (case_i += 1) { | 730 | while (case_i < cases_len - 1) : (case_i += 1) { |
| 734 | const case_death_count: u32 = l.extra[index]; | 731 | const case_death_count: u32 = l.extra[index]; |
| 735 | index += 1; | 732 | index += 1; |
| 736 | const case_deaths: []const Air.Inst.Index = @ptrCast(l.extra[index..][0..case_death_count]); | 733 | deaths[case_i] = @ptrCast(l.extra[index..][0..case_death_count]); |
| 737 | index += case_death_count; | 734 | index += case_death_count; |
| 738 | deaths.appendAssumeCapacity(case_deaths); | ||
| 739 | } | 735 | } |
| 740 | { | 736 | { |
| 741 | // Else | 737 | // Else |
| 742 | const else_deaths: []const Air.Inst.Index = @ptrCast(l.extra[index..][0..else_death_count]); | 738 | deaths[case_i] = @ptrCast(l.extra[index..][0..else_death_count]); |
| 743 | deaths.appendAssumeCapacity(else_deaths); | ||
| 744 | } | 739 | } |
| 745 | return SwitchBrTable{ | 740 | return .{ .deaths = deaths }; |
| 746 | .deaths = try deaths.toOwnedSlice(), | ||
| 747 | }; | ||
| 748 | } | 741 | } |
| 749 | 742 | ||
| 750 | /// Note that this information is technically redundant, but is useful for | 743 | /// Note that this information is technically redundant, but is useful for |
src/arch/x86_64/CodeGen.zig+273-26| ... | @@ -61,9 +61,10 @@ src_loc: Zcu.LazySrcLoc, | ... | @@ -61,9 +61,10 @@ src_loc: Zcu.LazySrcLoc, |
| 61 | eflags_inst: ?Air.Inst.Index = null, | 61 | eflags_inst: ?Air.Inst.Index = null, |
| 62 | 62 | ||
| 63 | /// MIR Instructions | 63 | /// MIR Instructions |
| 64 | mir_instructions: std.MultiArrayList(Mir.Inst) = .{}, | 64 | mir_instructions: std.MultiArrayList(Mir.Inst) = .empty, |
| 65 | /// MIR extra data | 65 | /// MIR extra data |
| 66 | mir_extra: std.ArrayListUnmanaged(u32) = .empty, | 66 | mir_extra: std.ArrayListUnmanaged(u32) = .empty, |
| 67 | mir_table: std.ArrayListUnmanaged(Mir.Inst.Index) = .empty, | ||
| 67 | 68 | ||
| 68 | /// Byte offset within the source file of the ending curly. | 69 | /// Byte offset within the source file of the ending curly. |
| 69 | end_di_line: u32, | 70 | end_di_line: u32, |
| ... | @@ -75,8 +76,8 @@ end_di_column: u32, | ... | @@ -75,8 +76,8 @@ end_di_column: u32, |
| 75 | exitlude_jump_relocs: std.ArrayListUnmanaged(Mir.Inst.Index) = .empty, | 76 | exitlude_jump_relocs: std.ArrayListUnmanaged(Mir.Inst.Index) = .empty, |
| 76 | 77 | ||
| 77 | reused_operands: std.StaticBitSet(Liveness.bpi - 1) = undefined, | 78 | reused_operands: std.StaticBitSet(Liveness.bpi - 1) = undefined, |
| 78 | const_tracking: ConstTrackingMap = .{}, | 79 | const_tracking: ConstTrackingMap = .empty, |
| 79 | inst_tracking: InstTrackingMap = .{}, | 80 | inst_tracking: InstTrackingMap = .empty, |
| 80 | 81 | ||
| 81 | // Key is the block instruction | 82 | // Key is the block instruction |
| 82 | blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, BlockData) = .empty, | 83 | blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, BlockData) = .empty, |
| ... | @@ -86,16 +87,26 @@ register_manager: RegisterManager = .{}, | ... | @@ -86,16 +87,26 @@ register_manager: RegisterManager = .{}, |
| 86 | /// Generation of the current scope, increments by 1 for every entered scope. | 87 | /// Generation of the current scope, increments by 1 for every entered scope. |
| 87 | scope_generation: u32 = 0, | 88 | scope_generation: u32 = 0, |
| 88 | 89 | ||
| 89 | frame_allocs: std.MultiArrayList(FrameAlloc) = .{}, | 90 | frame_allocs: std.MultiArrayList(FrameAlloc) = .empty, |
| 90 | free_frame_indices: std.AutoArrayHashMapUnmanaged(FrameIndex, void) = .empty, | 91 | free_frame_indices: std.AutoArrayHashMapUnmanaged(FrameIndex, void) = .empty, |
| 91 | frame_locs: std.MultiArrayList(Mir.FrameLoc) = .{}, | 92 | frame_locs: std.MultiArrayList(Mir.FrameLoc) = .empty, |
| 92 | 93 | ||
| 93 | loops: std.AutoHashMapUnmanaged(Air.Inst.Index, struct { | 94 | loops: std.AutoHashMapUnmanaged(Air.Inst.Index, struct { |
| 94 | /// The state to restore before branching. | 95 | /// The state to restore before branching. |
| 95 | state: State, | 96 | state: State, |
| 96 | /// The branch target. | 97 | /// The branch target. |
| 97 | target: Mir.Inst.Index, | 98 | target: Mir.Inst.Index, |
| 98 | }) = .{}, | 99 | }) = .empty, |
| 100 | loop_switches: std.AutoHashMapUnmanaged(Air.Inst.Index, struct { | ||
| 101 | start: u31, | ||
| 102 | len: u11, | ||
| 103 | min: Value, | ||
| 104 | else_relocs: union(enum) { | ||
| 105 | @"unreachable", | ||
| 106 | forward: std.ArrayListUnmanaged(Mir.Inst.Index), | ||
| 107 | backward: Mir.Inst.Index, | ||
| 108 | }, | ||
| 109 | }) = .empty, | ||
| 99 | 110 | ||
| 100 | next_temp_index: Temp.Index = @enumFromInt(0), | 111 | next_temp_index: Temp.Index = @enumFromInt(0), |
| 101 | temp_type: [Temp.Index.max]Type = undefined, | 112 | temp_type: [Temp.Index.max]Type = undefined, |
| ... | @@ -904,6 +915,7 @@ pub fn generate( | ... | @@ -904,6 +915,7 @@ pub fn generate( |
| 904 | function.free_frame_indices.deinit(gpa); | 915 | function.free_frame_indices.deinit(gpa); |
| 905 | function.frame_locs.deinit(gpa); | 916 | function.frame_locs.deinit(gpa); |
| 906 | function.loops.deinit(gpa); | 917 | function.loops.deinit(gpa); |
| 918 | function.loop_switches.deinit(gpa); | ||
| 907 | var block_it = function.blocks.valueIterator(); | 919 | var block_it = function.blocks.valueIterator(); |
| 908 | while (block_it.next()) |block| block.deinit(gpa); | 920 | while (block_it.next()) |block| block.deinit(gpa); |
| 909 | function.blocks.deinit(gpa); | 921 | function.blocks.deinit(gpa); |
| ... | @@ -912,6 +924,7 @@ pub fn generate( | ... | @@ -912,6 +924,7 @@ pub fn generate( |
| 912 | function.exitlude_jump_relocs.deinit(gpa); | 924 | function.exitlude_jump_relocs.deinit(gpa); |
| 913 | function.mir_instructions.deinit(gpa); | 925 | function.mir_instructions.deinit(gpa); |
| 914 | function.mir_extra.deinit(gpa); | 926 | function.mir_extra.deinit(gpa); |
| 927 | function.mir_table.deinit(gpa); | ||
| 915 | } | 928 | } |
| 916 | try function.inst_tracking.ensureTotalCapacity(gpa, Temp.Index.max); | 929 | try function.inst_tracking.ensureTotalCapacity(gpa, Temp.Index.max); |
| 917 | for (0..Temp.Index.max) |temp_index| { | 930 | for (0..Temp.Index.max) |temp_index| { |
| ... | @@ -978,6 +991,7 @@ pub fn generate( | ... | @@ -978,6 +991,7 @@ pub fn generate( |
| 978 | var mir: Mir = .{ | 991 | var mir: Mir = .{ |
| 979 | .instructions = function.mir_instructions.toOwnedSlice(), | 992 | .instructions = function.mir_instructions.toOwnedSlice(), |
| 980 | .extra = try function.mir_extra.toOwnedSlice(gpa), | 993 | .extra = try function.mir_extra.toOwnedSlice(gpa), |
| 994 | .table = try function.mir_table.toOwnedSlice(gpa), | ||
| 981 | .frame_locs = function.frame_locs.toOwnedSlice(), | 995 | .frame_locs = function.frame_locs.toOwnedSlice(), |
| 982 | }; | 996 | }; |
| 983 | defer mir.deinit(gpa); | 997 | defer mir.deinit(gpa); |
| ... | @@ -1012,7 +1026,6 @@ pub fn generate( | ... | @@ -1012,7 +1026,6 @@ pub fn generate( |
| 1012 | }, | 1026 | }, |
| 1013 | .prev_di_pc = 0, | 1027 | .prev_di_pc = 0, |
| 1014 | }; | 1028 | }; |
| 1015 | defer emit.deinit(); | ||
| 1016 | emit.emitMir() catch |err| switch (err) { | 1029 | emit.emitMir() catch |err| switch (err) { |
| 1017 | error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?), | 1030 | error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?), |
| 1018 | 1031 | ||
| ... | @@ -1056,6 +1069,7 @@ pub fn generateLazy( | ... | @@ -1056,6 +1069,7 @@ pub fn generateLazy( |
| 1056 | defer { | 1069 | defer { |
| 1057 | function.mir_instructions.deinit(gpa); | 1070 | function.mir_instructions.deinit(gpa); |
| 1058 | function.mir_extra.deinit(gpa); | 1071 | function.mir_extra.deinit(gpa); |
| 1072 | function.mir_table.deinit(gpa); | ||
| 1059 | } | 1073 | } |
| 1060 | 1074 | ||
| 1061 | function.genLazy(lazy_sym) catch |err| switch (err) { | 1075 | function.genLazy(lazy_sym) catch |err| switch (err) { |
| ... | @@ -1067,6 +1081,7 @@ pub fn generateLazy( | ... | @@ -1067,6 +1081,7 @@ pub fn generateLazy( |
| 1067 | var mir: Mir = .{ | 1081 | var mir: Mir = .{ |
| 1068 | .instructions = function.mir_instructions.toOwnedSlice(), | 1082 | .instructions = function.mir_instructions.toOwnedSlice(), |
| 1069 | .extra = try function.mir_extra.toOwnedSlice(gpa), | 1083 | .extra = try function.mir_extra.toOwnedSlice(gpa), |
| 1084 | .table = try function.mir_table.toOwnedSlice(gpa), | ||
| 1070 | .frame_locs = function.frame_locs.toOwnedSlice(), | 1085 | .frame_locs = function.frame_locs.toOwnedSlice(), |
| 1071 | }; | 1086 | }; |
| 1072 | defer mir.deinit(gpa); | 1087 | defer mir.deinit(gpa); |
| ... | @@ -1093,7 +1108,6 @@ pub fn generateLazy( | ... | @@ -1093,7 +1108,6 @@ pub fn generateLazy( |
| 1093 | .prev_di_loc = undefined, // no debug info yet | 1108 | .prev_di_loc = undefined, // no debug info yet |
| 1094 | .prev_di_pc = undefined, // no debug info yet | 1109 | .prev_di_pc = undefined, // no debug info yet |
| 1095 | }; | 1110 | }; |
| 1096 | defer emit.deinit(); | ||
| 1097 | emit.emitMir() catch |err| switch (err) { | 1111 | emit.emitMir() catch |err| switch (err) { |
| 1098 | error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?), | 1112 | error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?), |
| 1099 | error.InvalidInstruction => return function.fail("failed to find a viable x86 instruction (Zig compiler bug)", .{}), | 1113 | error.InvalidInstruction => return function.fail("failed to find a viable x86 instruction (Zig compiler bug)", .{}), |
| ... | @@ -1161,6 +1175,7 @@ fn formatWipMir( | ... | @@ -1161,6 +1175,7 @@ fn formatWipMir( |
| 1161 | .mir = .{ | 1175 | .mir = .{ |
| 1162 | .instructions = data.self.mir_instructions.slice(), | 1176 | .instructions = data.self.mir_instructions.slice(), |
| 1163 | .extra = data.self.mir_extra.items, | 1177 | .extra = data.self.mir_extra.items, |
| 1178 | .table = data.self.mir_table.items, | ||
| 1164 | .frame_locs = (std.MultiArrayList(Mir.FrameLoc){}).slice(), | 1179 | .frame_locs = (std.MultiArrayList(Mir.FrameLoc){}).slice(), |
| 1165 | }, | 1180 | }, |
| 1166 | .cc = .auto, | 1181 | .cc = .auto, |
| ... | @@ -20748,25 +20763,195 @@ fn lowerBlock(self: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index | ... | @@ -20748,25 +20763,195 @@ fn lowerBlock(self: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index |
| 20748 | self.getValueIfFree(tracking.short, inst); | 20763 | self.getValueIfFree(tracking.short, inst); |
| 20749 | } | 20764 | } |
| 20750 | 20765 | ||
| 20751 | fn lowerSwitchBr(self: *CodeGen, inst: Air.Inst.Index, switch_br: Air.UnwrappedSwitch, condition: MCValue) !void { | 20766 | fn lowerSwitchBr( |
| 20767 | self: *CodeGen, | ||
| 20768 | inst: Air.Inst.Index, | ||
| 20769 | switch_br: Air.UnwrappedSwitch, | ||
| 20770 | condition: MCValue, | ||
| 20771 | condition_dies: bool, | ||
| 20772 | is_loop: bool, | ||
| 20773 | ) !void { | ||
| 20752 | const zcu = self.pt.zcu; | 20774 | const zcu = self.pt.zcu; |
| 20753 | const condition_ty = self.typeOf(switch_br.operand); | 20775 | const condition_ty = self.typeOf(switch_br.operand); |
| 20754 | const liveness = try self.liveness.getSwitchBr(self.gpa, inst, switch_br.cases_len + 1); | ||
| 20755 | defer self.gpa.free(liveness.deaths); | ||
| 20756 | 20776 | ||
| 20757 | const signedness = switch (condition_ty.zigTypeTag(zcu)) { | 20777 | const ExpectedContents = extern struct { |
| 20758 | .bool, .pointer => .unsigned, | 20778 | liveness_deaths: [1 << 8 | 1]Air.Inst.Index, |
| 20759 | .int, .@"enum", .error_set => condition_ty.intInfo(zcu).signedness, | 20779 | bigint_limbs: [std.math.big.int.calcTwosCompLimbCount(1 << 8)]std.math.big.Limb, |
| 20760 | else => unreachable, | 20780 | relocs: [1 << 6]Mir.Inst.Index, |
| 20761 | }; | 20781 | }; |
| 20782 | var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) = | ||
| 20783 | std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa); | ||
| 20784 | const allocator = stack.get(); | ||
| 20762 | 20785 | ||
| 20763 | self.scope_generation += 1; | 20786 | self.scope_generation += 1; |
| 20764 | const state = try self.saveState(); | 20787 | const state = try self.saveState(); |
| 20765 | 20788 | ||
| 20766 | var it = switch_br.iterateCases(); | 20789 | const liveness = try self.liveness.getSwitchBr(allocator, inst, switch_br.cases_len + 1); |
| 20767 | while (it.next()) |case| { | 20790 | defer allocator.free(liveness.deaths); |
| 20768 | var relocs = try self.gpa.alloc(Mir.Inst.Index, case.items.len + case.ranges.len); | 20791 | |
| 20769 | defer self.gpa.free(relocs); | 20792 | if (!self.mod.pic and self.target.ofmt == .elf) table: { |
| 20793 | var prong_items: u32 = 0; | ||
| 20794 | var min: ?Value = null; | ||
| 20795 | var max: ?Value = null; | ||
| 20796 | { | ||
| 20797 | var cases_it = switch_br.iterateCases(); | ||
| 20798 | while (cases_it.next()) |case| { | ||
| 20799 | prong_items += @intCast(case.items.len + case.ranges.len); | ||
| 20800 | for (case.items) |item| { | ||
| 20801 | const val = Value.fromInterned(item.toInterned().?); | ||
| 20802 | if (min == null or val.compareHetero(.lt, min.?, zcu)) min = val; | ||
| 20803 | if (max == null or val.compareHetero(.gt, max.?, zcu)) max = val; | ||
| 20804 | } | ||
| 20805 | for (case.ranges) |range| { | ||
| 20806 | const low = Value.fromInterned(range[0].toInterned().?); | ||
| 20807 | if (min == null or low.compareHetero(.lt, min.?, zcu)) min = low; | ||
| 20808 | const high = Value.fromInterned(range[1].toInterned().?); | ||
| 20809 | if (max == null or high.compareHetero(.gt, max.?, zcu)) max = high; | ||
| 20810 | } | ||
| 20811 | } | ||
| 20812 | } | ||
| 20813 | // This condition also triggers for switches with no non-else prongs and switches on bool. | ||
| 20814 | if (prong_items < 1 << 2 or prong_items > 1 << 8) break :table; | ||
| 20815 | |||
| 20816 | var min_space: Value.BigIntSpace = undefined; | ||
| 20817 | const min_bigint = min.?.toBigInt(&min_space, zcu); | ||
| 20818 | var max_space: Value.BigIntSpace = undefined; | ||
| 20819 | const max_bigint = max.?.toBigInt(&max_space, zcu); | ||
| 20820 | const limbs = try allocator.alloc( | ||
| 20821 | std.math.big.Limb, | ||
| 20822 | @max(min_bigint.limbs.len, max_bigint.limbs.len) + 1, | ||
| 20823 | ); | ||
| 20824 | defer allocator.free(limbs); | ||
| 20825 | const table_len = table_len: { | ||
| 20826 | var table_len_bigint: std.math.big.int.Mutable = .{ .limbs = limbs, .positive = undefined, .len = undefined }; | ||
| 20827 | table_len_bigint.sub(max_bigint, min_bigint); | ||
| 20828 | assert(table_len_bigint.positive); // min <= max | ||
| 20829 | break :table_len @as(u11, table_len_bigint.toConst().to(u10) catch break :table) + 1; // no more than a 1024 entry table | ||
| 20830 | }; | ||
| 20831 | assert(prong_items <= table_len); // each prong item introduces at least one unique integer to the range | ||
| 20832 | if (prong_items < table_len >> 2) break :table; // no more than 75% waste | ||
| 20833 | |||
| 20834 | const condition_index = if (condition_dies and condition.isModifiable()) condition else condition_index: { | ||
| 20835 | const condition_index = try self.allocTempRegOrMem(condition_ty, true); | ||
| 20836 | try self.genCopy(condition_ty, condition_index, condition, .{}); | ||
| 20837 | break :condition_index condition_index; | ||
| 20838 | }; | ||
| 20839 | try self.spillEflagsIfOccupied(); | ||
| 20840 | if (min.?.orderAgainstZero(zcu).compare(.neq)) try self.genBinOpMir( | ||
| 20841 | .{ ._, .sub }, | ||
| 20842 | condition_ty, | ||
| 20843 | condition_index, | ||
| 20844 | .{ .air_ref = Air.internedToRef(min.?.toIntern()) }, | ||
| 20845 | ); | ||
| 20846 | const else_reloc = if (switch_br.else_body_len > 0) else_reloc: { | ||
| 20847 | try self.genBinOpMir(.{ ._, .cmp }, condition_ty, condition_index, .{ .immediate = table_len - 1 }); | ||
| 20848 | break :else_reloc try self.asmJccReloc(.a, undefined); | ||
| 20849 | } else undefined; | ||
| 20850 | const table_start: u31 = @intCast(self.mir_table.items.len); | ||
| 20851 | { | ||
| 20852 | const condition_index_reg = if (condition_index.isRegister()) | ||
| 20853 | condition_index.getReg().? | ||
| 20854 | else | ||
| 20855 | try self.copyToTmpRegister(.usize, condition_index); | ||
| 20856 | const condition_index_lock = self.register_manager.lockReg(condition_index_reg); | ||
| 20857 | defer if (condition_index_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 20858 | try self.truncateRegister(condition_ty, condition_index_reg); | ||
| 20859 | const ptr_size = @divExact(self.target.ptrBitWidth(), 8); | ||
| 20860 | try self.asmMemory(.{ ._, .jmp }, .{ | ||
| 20861 | .base = .table, | ||
| 20862 | .mod = .{ .rm = .{ | ||
| 20863 | .size = .ptr, | ||
| 20864 | .index = registerAlias(condition_index_reg, ptr_size), | ||
| 20865 | .scale = .fromFactor(@intCast(ptr_size)), | ||
| 20866 | .disp = table_start * ptr_size, | ||
| 20867 | } }, | ||
| 20868 | }); | ||
| 20869 | } | ||
| 20870 | const else_reloc_marker: u32 = 0; | ||
| 20871 | assert(self.mir_instructions.len > else_reloc_marker); | ||
| 20872 | try self.mir_table.appendNTimes(self.gpa, else_reloc_marker, table_len); | ||
| 20873 | if (is_loop) try self.loop_switches.putNoClobber(self.gpa, inst, .{ | ||
| 20874 | .start = table_start, | ||
| 20875 | .len = table_len, | ||
| 20876 | .min = min.?, | ||
| 20877 | .else_relocs = if (switch_br.else_body_len > 0) .{ .forward = .empty } else .@"unreachable", | ||
| 20878 | }); | ||
| 20879 | defer if (is_loop) { | ||
| 20880 | var loop_switch_data = self.loop_switches.fetchRemove(inst).?.value; | ||
| 20881 | switch (loop_switch_data.else_relocs) { | ||
| 20882 | .@"unreachable", .backward => {}, | ||
| 20883 | .forward => |*else_relocs| else_relocs.deinit(self.gpa), | ||
| 20884 | } | ||
| 20885 | }; | ||
| 20886 | var cases_it = switch_br.iterateCases(); | ||
| 20887 | while (cases_it.next()) |case| { | ||
| 20888 | { | ||
| 20889 | const table = self.mir_table.items[table_start..][0..table_len]; | ||
| 20890 | for (case.items) |item| { | ||
| 20891 | const val = Value.fromInterned(item.toInterned().?); | ||
| 20892 | var val_space: Value.BigIntSpace = undefined; | ||
| 20893 | const val_bigint = val.toBigInt(&val_space, zcu); | ||
| 20894 | var index_bigint: std.math.big.int.Mutable = .{ .limbs = limbs, .positive = undefined, .len = undefined }; | ||
| 20895 | index_bigint.sub(val_bigint, min_bigint); | ||
| 20896 | table[index_bigint.toConst().to(u10) catch unreachable] = @intCast(self.mir_instructions.len); | ||
| 20897 | } | ||
| 20898 | for (case.ranges) |range| { | ||
| 20899 | var low_space: Value.BigIntSpace = undefined; | ||
| 20900 | const low_bigint = Value.fromInterned(range[0].toInterned().?).toBigInt(&low_space, zcu); | ||
| 20901 | var high_space: Value.BigIntSpace = undefined; | ||
| 20902 | const high_bigint = Value.fromInterned(range[1].toInterned().?).toBigInt(&high_space, zcu); | ||
| 20903 | var index_bigint: std.math.big.int.Mutable = .{ .limbs = limbs, .positive = undefined, .len = undefined }; | ||
| 20904 | index_bigint.sub(low_bigint, min_bigint); | ||
| 20905 | const start = index_bigint.toConst().to(u10) catch unreachable; | ||
| 20906 | index_bigint.sub(high_bigint, min_bigint); | ||
| 20907 | const end = @as(u11, index_bigint.toConst().to(u10) catch unreachable) + 1; | ||
| 20908 | @memset(table[start..end], @intCast(self.mir_instructions.len)); | ||
| 20909 | } | ||
| 20910 | } | ||
| 20911 | |||
| 20912 | for (liveness.deaths[case.idx]) |operand| try self.processDeath(operand); | ||
| 20913 | |||
| 20914 | try self.genBodyBlock(case.body); | ||
| 20915 | try self.restoreState(state, &.{}, .{ | ||
| 20916 | .emit_instructions = false, | ||
| 20917 | .update_tracking = true, | ||
| 20918 | .resurrect = true, | ||
| 20919 | .close_scope = true, | ||
| 20920 | }); | ||
| 20921 | } | ||
| 20922 | if (switch_br.else_body_len > 0) { | ||
| 20923 | const else_body = cases_it.elseBody(); | ||
| 20924 | |||
| 20925 | const else_deaths = liveness.deaths.len - 1; | ||
| 20926 | for (liveness.deaths[else_deaths]) |operand| try self.processDeath(operand); | ||
| 20927 | |||
| 20928 | self.performReloc(else_reloc); | ||
| 20929 | if (is_loop) { | ||
| 20930 | const loop_switch_data = self.loop_switches.getPtr(inst).?; | ||
| 20931 | for (loop_switch_data.else_relocs.forward.items) |reloc| self.performReloc(reloc); | ||
| 20932 | loop_switch_data.else_relocs.forward.deinit(self.gpa); | ||
| 20933 | loop_switch_data.else_relocs = .{ .backward = @intCast(self.mir_instructions.len) }; | ||
| 20934 | } | ||
| 20935 | for (self.mir_table.items[table_start..][0..table_len]) |*entry| if (entry.* == else_reloc_marker) { | ||
| 20936 | entry.* = @intCast(self.mir_instructions.len); | ||
| 20937 | }; | ||
| 20938 | |||
| 20939 | try self.genBodyBlock(else_body); | ||
| 20940 | try self.restoreState(state, &.{}, .{ | ||
| 20941 | .emit_instructions = false, | ||
| 20942 | .update_tracking = true, | ||
| 20943 | .resurrect = true, | ||
| 20944 | .close_scope = true, | ||
| 20945 | }); | ||
| 20946 | } | ||
| 20947 | return; | ||
| 20948 | } | ||
| 20949 | |||
| 20950 | const signedness = if (condition_ty.isAbiInt(zcu)) condition_ty.intInfo(zcu).signedness else .unsigned; | ||
| 20951 | var cases_it = switch_br.iterateCases(); | ||
| 20952 | while (cases_it.next()) |case| { | ||
| 20953 | var relocs = try allocator.alloc(Mir.Inst.Index, case.items.len + case.ranges.len); | ||
| 20954 | defer allocator.free(relocs); | ||
| 20770 | 20955 | ||
| 20771 | try self.spillEflagsIfOccupied(); | 20956 | try self.spillEflagsIfOccupied(); |
| 20772 | for (case.items, relocs[0..case.items.len]) |item, *reloc| { | 20957 | for (case.items, relocs[0..case.items.len]) |item, *reloc| { |
| ... | @@ -20849,9 +21034,8 @@ fn lowerSwitchBr(self: *CodeGen, inst: Air.Inst.Index, switch_br: Air.UnwrappedS | ... | @@ -20849,9 +21034,8 @@ fn lowerSwitchBr(self: *CodeGen, inst: Air.Inst.Index, switch_br: Air.UnwrappedS |
| 20849 | // Relocate the "skip" branch to fall through to the next case. | 21034 | // Relocate the "skip" branch to fall through to the next case. |
| 20850 | self.performReloc(skip_case_reloc); | 21035 | self.performReloc(skip_case_reloc); |
| 20851 | } | 21036 | } |
| 20852 | |||
| 20853 | if (switch_br.else_body_len > 0) { | 21037 | if (switch_br.else_body_len > 0) { |
| 20854 | const else_body = it.elseBody(); | 21038 | const else_body = cases_it.elseBody(); |
| 20855 | 21039 | ||
| 20856 | const else_deaths = liveness.deaths.len - 1; | 21040 | const else_deaths = liveness.deaths.len - 1; |
| 20857 | for (liveness.deaths[else_deaths]) |operand| try self.processDeath(operand); | 21041 | for (liveness.deaths[else_deaths]) |operand| try self.processDeath(operand); |
| ... | @@ -20873,11 +21057,11 @@ fn airSwitchBr(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -20873,11 +21057,11 @@ fn airSwitchBr(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 20873 | // If the condition dies here in this switch instruction, process | 21057 | // If the condition dies here in this switch instruction, process |
| 20874 | // that death now instead of later as this has an effect on | 21058 | // that death now instead of later as this has an effect on |
| 20875 | // whether it needs to be spilled in the branches | 21059 | // whether it needs to be spilled in the branches |
| 20876 | if (self.liveness.operandDies(inst, 0)) { | 21060 | const condition_dies = self.liveness.operandDies(inst, 0); |
| 21061 | if (condition_dies) { | ||
| 20877 | if (switch_br.operand.toIndex()) |op_inst| try self.processDeath(op_inst); | 21062 | if (switch_br.operand.toIndex()) |op_inst| try self.processDeath(op_inst); |
| 20878 | } | 21063 | } |
| 20879 | 21064 | try self.lowerSwitchBr(inst, switch_br, condition, condition_dies, false); | |
| 20880 | try self.lowerSwitchBr(inst, switch_br, condition); | ||
| 20881 | 21065 | ||
| 20882 | // We already took care of pl_op.operand earlier, so there's nothing left to do | 21066 | // We already took care of pl_op.operand earlier, so there's nothing left to do |
| 20883 | } | 21067 | } |
| ... | @@ -20915,7 +21099,7 @@ fn airLoopSwitchBr(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -20915,7 +21099,7 @@ fn airLoopSwitchBr(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 20915 | // Stop tracking block result without forgetting tracking info | 21099 | // Stop tracking block result without forgetting tracking info |
| 20916 | try self.freeValue(mat_cond); | 21100 | try self.freeValue(mat_cond); |
| 20917 | 21101 | ||
| 20918 | try self.lowerSwitchBr(inst, switch_br, mat_cond); | 21102 | try self.lowerSwitchBr(inst, switch_br, mat_cond, true, true); |
| 20919 | 21103 | ||
| 20920 | try self.processDeath(inst); | 21104 | try self.processDeath(inst); |
| 20921 | } | 21105 | } |
| ... | @@ -20924,8 +21108,67 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -20924,8 +21108,67 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 20924 | const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br; | 21108 | const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 20925 | 21109 | ||
| 20926 | const block_ty = self.typeOfIndex(br.block_inst); | 21110 | const block_ty = self.typeOfIndex(br.block_inst); |
| 20927 | const block_tracking = self.inst_tracking.getPtr(br.block_inst).?; | ||
| 20928 | const loop_data = self.loops.getPtr(br.block_inst).?; | 21111 | const loop_data = self.loops.getPtr(br.block_inst).?; |
| 21112 | if (self.loop_switches.getPtr(br.block_inst)) |table| { | ||
| 21113 | // Process operand death so that it is properly accounted for in the State below. | ||
| 21114 | const condition_dies = self.liveness.operandDies(inst, 0); | ||
| 21115 | |||
| 21116 | try self.restoreState(loop_data.state, &.{}, .{ | ||
| 21117 | .emit_instructions = true, | ||
| 21118 | .update_tracking = false, | ||
| 21119 | .resurrect = false, | ||
| 21120 | .close_scope = false, | ||
| 21121 | }); | ||
| 21122 | |||
| 21123 | const condition_ty = self.typeOf(br.operand); | ||
| 21124 | const condition = try self.resolveInst(br.operand); | ||
| 21125 | const condition_index = if (condition_dies and condition.isModifiable()) condition else condition_index: { | ||
| 21126 | const condition_index = try self.allocTempRegOrMem(condition_ty, true); | ||
| 21127 | try self.genCopy(condition_ty, condition_index, condition, .{}); | ||
| 21128 | break :condition_index condition_index; | ||
| 21129 | }; | ||
| 21130 | try self.spillEflagsIfOccupied(); | ||
| 21131 | if (table.min.orderAgainstZero(self.pt.zcu).compare(.neq)) try self.genBinOpMir( | ||
| 21132 | .{ ._, .sub }, | ||
| 21133 | condition_ty, | ||
| 21134 | condition_index, | ||
| 21135 | .{ .air_ref = Air.internedToRef(table.min.toIntern()) }, | ||
| 21136 | ); | ||
| 21137 | switch (table.else_relocs) { | ||
| 21138 | .@"unreachable" => {}, | ||
| 21139 | .forward => |*else_relocs| { | ||
| 21140 | try self.genBinOpMir(.{ ._, .cmp }, condition_ty, condition_index, .{ .immediate = table.len - 1 }); | ||
| 21141 | try else_relocs.append(self.gpa, try self.asmJccReloc(.a, undefined)); | ||
| 21142 | }, | ||
| 21143 | .backward => |else_reloc| { | ||
| 21144 | try self.genBinOpMir(.{ ._, .cmp }, condition_ty, condition_index, .{ .immediate = table.len - 1 }); | ||
| 21145 | _ = try self.asmJccReloc(.a, else_reloc); | ||
| 21146 | }, | ||
| 21147 | } | ||
| 21148 | { | ||
| 21149 | const condition_index_reg = if (condition_index.isRegister()) | ||
| 21150 | condition_index.getReg().? | ||
| 21151 | else | ||
| 21152 | try self.copyToTmpRegister(.usize, condition_index); | ||
| 21153 | const condition_index_lock = self.register_manager.lockReg(condition_index_reg); | ||
| 21154 | defer if (condition_index_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 21155 | try self.truncateRegister(condition_ty, condition_index_reg); | ||
| 21156 | const ptr_size = @divExact(self.target.ptrBitWidth(), 8); | ||
| 21157 | try self.asmMemory(.{ ._, .jmp }, .{ | ||
| 21158 | .base = .table, | ||
| 21159 | .mod = .{ .rm = .{ | ||
| 21160 | .size = .ptr, | ||
| 21161 | .index = registerAlias(condition_index_reg, ptr_size), | ||
| 21162 | .scale = .fromFactor(@intCast(ptr_size)), | ||
| 21163 | .disp = @intCast(table.start * ptr_size), | ||
| 21164 | } }, | ||
| 21165 | }); | ||
| 21166 | } | ||
| 21167 | |||
| 21168 | return self.finishAir(inst, .none, .{ br.operand, .none, .none }); | ||
| 21169 | } | ||
| 21170 | |||
| 21171 | const block_tracking = self.inst_tracking.getPtr(br.block_inst).?; | ||
| 20929 | done: { | 21172 | done: { |
| 20930 | try self.getValue(block_tracking.short, null); | 21173 | try self.getValue(block_tracking.short, null); |
| 20931 | const src_mcv = try self.resolveInst(br.operand); | 21174 | const src_mcv = try self.resolveInst(br.operand); |
| ... | @@ -22543,6 +22786,7 @@ fn genSetMem( | ... | @@ -22543,6 +22786,7 @@ fn genSetMem( |
| 22543 | .none => .{ .immediate = @bitCast(@as(i64, disp)) }, | 22786 | .none => .{ .immediate = @bitCast(@as(i64, disp)) }, |
| 22544 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, | 22787 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, |
| 22545 | .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } }, | 22788 | .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } }, |
| 22789 | .table => unreachable, | ||
| 22546 | .reloc => |sym_index| .{ .lea_symbol = .{ .sym_index = sym_index, .off = disp } }, | 22790 | .reloc => |sym_index| .{ .lea_symbol = .{ .sym_index = sym_index, .off = disp } }, |
| 22547 | }; | 22791 | }; |
| 22548 | switch (src_mcv) { | 22792 | switch (src_mcv) { |
| ... | @@ -22652,6 +22896,7 @@ fn genSetMem( | ... | @@ -22652,6 +22896,7 @@ fn genSetMem( |
| 22652 | .index = frame_index, | 22896 | .index = frame_index, |
| 22653 | .off = disp, | 22897 | .off = disp, |
| 22654 | }).compare(.gte, src_align), | 22898 | }).compare(.gte, src_align), |
| 22899 | .table => unreachable, | ||
| 22655 | .reloc => false, | 22900 | .reloc => false, |
| 22656 | })).write( | 22901 | })).write( |
| 22657 | self, | 22902 | self, |
| ... | @@ -23260,6 +23505,7 @@ fn airCmpxchg(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -23260,6 +23505,7 @@ fn airCmpxchg(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 23260 | const ptr_lock = switch (ptr_mem.base) { | 23505 | const ptr_lock = switch (ptr_mem.base) { |
| 23261 | .none, .frame, .reloc => null, | 23506 | .none, .frame, .reloc => null, |
| 23262 | .reg => |reg| self.register_manager.lockReg(reg), | 23507 | .reg => |reg| self.register_manager.lockReg(reg), |
| 23508 | .table => unreachable, | ||
| 23263 | }; | 23509 | }; |
| 23264 | defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); | 23510 | defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); |
| 23265 | 23511 | ||
| ... | @@ -23327,6 +23573,7 @@ fn atomicOp( | ... | @@ -23327,6 +23573,7 @@ fn atomicOp( |
| 23327 | const mem_lock = switch (ptr_mem.base) { | 23573 | const mem_lock = switch (ptr_mem.base) { |
| 23328 | .none, .frame, .reloc => null, | 23574 | .none, .frame, .reloc => null, |
| 23329 | .reg => |reg| self.register_manager.lockReg(reg), | 23575 | .reg => |reg| self.register_manager.lockReg(reg), |
| 23576 | .table => unreachable, | ||
| 23330 | }; | 23577 | }; |
| 23331 | defer if (mem_lock) |lock| self.register_manager.unlockReg(lock); | 23578 | defer if (mem_lock) |lock| self.register_manager.unlockReg(lock); |
| 23332 | 23579 |
src/arch/x86_64/Emit.zig+58-34| ... | @@ -10,22 +10,21 @@ prev_di_loc: Loc, | ... | @@ -10,22 +10,21 @@ prev_di_loc: Loc, |
| 10 | /// Relative to the beginning of `code`. | 10 | /// Relative to the beginning of `code`. |
| 11 | prev_di_pc: usize, | 11 | prev_di_pc: usize, |
| 12 | 12 | ||
| 13 | code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .empty, | ||
| 14 | relocs: std.ArrayListUnmanaged(Reloc) = .empty, | ||
| 15 | |||
| 16 | pub const Error = Lower.Error || error{ | 13 | pub const Error = Lower.Error || error{ |
| 17 | EmitFail, | 14 | EmitFail, |
| 18 | } || link.File.UpdateDebugInfoError; | 15 | } || link.File.UpdateDebugInfoError; |
| 19 | 16 | ||
| 20 | pub fn emitMir(emit: *Emit) Error!void { | 17 | pub fn emitMir(emit: *Emit) Error!void { |
| 21 | const gpa = emit.lower.bin_file.comp.gpa; | 18 | const gpa = emit.lower.bin_file.comp.gpa; |
| 19 | const code_offset_mapping = try emit.lower.allocator.alloc(u32, emit.lower.mir.instructions.len); | ||
| 20 | defer emit.lower.allocator.free(code_offset_mapping); | ||
| 21 | var relocs: std.ArrayListUnmanaged(Reloc) = .empty; | ||
| 22 | defer relocs.deinit(emit.lower.allocator); | ||
| 23 | var table_relocs: std.ArrayListUnmanaged(TableReloc) = .empty; | ||
| 24 | defer table_relocs.deinit(emit.lower.allocator); | ||
| 22 | for (0..emit.lower.mir.instructions.len) |mir_i| { | 25 | for (0..emit.lower.mir.instructions.len) |mir_i| { |
| 23 | const mir_index: Mir.Inst.Index = @intCast(mir_i); | 26 | const mir_index: Mir.Inst.Index = @intCast(mir_i); |
| 24 | try emit.code_offset_mapping.putNoClobber( | 27 | code_offset_mapping[mir_index] = @intCast(emit.code.items.len); |
| 25 | emit.lower.allocator, | ||
| 26 | mir_index, | ||
| 27 | @intCast(emit.code.items.len), | ||
| 28 | ); | ||
| 29 | const lowered = try emit.lower.lowerMir(mir_index); | 28 | const lowered = try emit.lower.lowerMir(mir_index); |
| 30 | var lowered_relocs = lowered.relocs; | 29 | var lowered_relocs = lowered.relocs; |
| 31 | for (lowered.insts, 0..) |lowered_inst, lowered_index| { | 30 | for (lowered.insts, 0..) |lowered_inst, lowered_index| { |
| ... | @@ -89,13 +88,17 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -89,13 +88,17 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 89 | lowered_relocs[0].lowered_inst_index == lowered_index) : ({ | 88 | lowered_relocs[0].lowered_inst_index == lowered_index) : ({ |
| 90 | lowered_relocs = lowered_relocs[1..]; | 89 | lowered_relocs = lowered_relocs[1..]; |
| 91 | }) switch (lowered_relocs[0].target) { | 90 | }) switch (lowered_relocs[0].target) { |
| 92 | .inst => |target| try emit.relocs.append(emit.lower.allocator, .{ | 91 | .inst => |target| try relocs.append(emit.lower.allocator, .{ |
| 93 | .source = start_offset, | 92 | .source = start_offset, |
| 94 | .source_offset = end_offset - 4, | 93 | .source_offset = end_offset - 4, |
| 95 | .target = target, | 94 | .target = target, |
| 96 | .target_offset = lowered_relocs[0].off, | 95 | .target_offset = lowered_relocs[0].off, |
| 97 | .length = @intCast(end_offset - start_offset), | 96 | .length = @intCast(end_offset - start_offset), |
| 98 | }), | 97 | }), |
| 98 | .table => try table_relocs.append(emit.lower.allocator, .{ | ||
| 99 | .source_offset = end_offset - 4, | ||
| 100 | .target_offset = lowered_relocs[0].off, | ||
| 101 | }), | ||
| 99 | .linker_extern_fn => |sym_index| if (emit.lower.bin_file.cast(.elf)) |elf_file| { | 102 | .linker_extern_fn => |sym_index| if (emit.lower.bin_file.cast(.elf)) |elf_file| { |
| 100 | // Add relocation to the decl. | 103 | // Add relocation to the decl. |
| 101 | const zo = elf_file.zigObjectPtr().?; | 104 | const zo = elf_file.zigObjectPtr().?; |
| ... | @@ -103,7 +106,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -103,7 +106,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 103 | const r_type = @intFromEnum(std.elf.R_X86_64.PLT32); | 106 | const r_type = @intFromEnum(std.elf.R_X86_64.PLT32); |
| 104 | try atom_ptr.addReloc(gpa, .{ | 107 | try atom_ptr.addReloc(gpa, .{ |
| 105 | .r_offset = end_offset - 4, | 108 | .r_offset = end_offset - 4, |
| 106 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, | 109 | .r_info = @as(u64, sym_index) << 32 | r_type, |
| 107 | .r_addend = lowered_relocs[0].off - 4, | 110 | .r_addend = lowered_relocs[0].off - 4, |
| 108 | }, zo); | 111 | }, zo); |
| 109 | } else if (emit.lower.bin_file.cast(.macho)) |macho_file| { | 112 | } else if (emit.lower.bin_file.cast(.macho)) |macho_file| { |
| ... | @@ -150,7 +153,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -150,7 +153,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 150 | const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD); | 153 | const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD); |
| 151 | try atom.addReloc(gpa, .{ | 154 | try atom.addReloc(gpa, .{ |
| 152 | .r_offset = end_offset - 4, | 155 | .r_offset = end_offset - 4, |
| 153 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, | 156 | .r_info = @as(u64, sym_index) << 32 | r_type, |
| 154 | .r_addend = lowered_relocs[0].off - 4, | 157 | .r_addend = lowered_relocs[0].off - 4, |
| 155 | }, zo); | 158 | }, zo); |
| 156 | }, | 159 | }, |
| ... | @@ -161,7 +164,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -161,7 +164,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 161 | const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32); | 164 | const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32); |
| 162 | try atom.addReloc(gpa, .{ | 165 | try atom.addReloc(gpa, .{ |
| 163 | .r_offset = end_offset - 4, | 166 | .r_offset = end_offset - 4, |
| 164 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, | 167 | .r_info = @as(u64, sym_index) << 32 | r_type, |
| 165 | .r_addend = lowered_relocs[0].off, | 168 | .r_addend = lowered_relocs[0].off, |
| 166 | }, zo); | 169 | }, zo); |
| 167 | }, | 170 | }, |
| ... | @@ -176,7 +179,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -176,7 +179,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 176 | @intFromEnum(std.elf.R_X86_64.PC32); | 179 | @intFromEnum(std.elf.R_X86_64.PC32); |
| 177 | try atom.addReloc(gpa, .{ | 180 | try atom.addReloc(gpa, .{ |
| 178 | .r_offset = end_offset - 4, | 181 | .r_offset = end_offset - 4, |
| 179 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, | 182 | .r_info = @as(u64, sym_index) << 32 | r_type, |
| 180 | .r_addend = lowered_relocs[0].off - 4, | 183 | .r_addend = lowered_relocs[0].off - 4, |
| 181 | }, zo); | 184 | }, zo); |
| 182 | } else { | 185 | } else { |
| ... | @@ -186,7 +189,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -186,7 +189,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 186 | @intFromEnum(std.elf.R_X86_64.@"32"); | 189 | @intFromEnum(std.elf.R_X86_64.@"32"); |
| 187 | try atom.addReloc(gpa, .{ | 190 | try atom.addReloc(gpa, .{ |
| 188 | .r_offset = end_offset - 4, | 191 | .r_offset = end_offset - 4, |
| 189 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, | 192 | .r_info = @as(u64, sym_index) << 32 | r_type, |
| 190 | .r_addend = lowered_relocs[0].off, | 193 | .r_addend = lowered_relocs[0].off, |
| 191 | }, zo); | 194 | }, zo); |
| 192 | } | 195 | } |
| ... | @@ -412,7 +415,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -412,7 +415,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 412 | loc_buf[0] = switch (mem.base()) { | 415 | loc_buf[0] = switch (mem.base()) { |
| 413 | .none => .{ .constu = 0 }, | 416 | .none => .{ .constu = 0 }, |
| 414 | .reg => |reg| .{ .breg = reg.dwarfNum() }, | 417 | .reg => |reg| .{ .breg = reg.dwarfNum() }, |
| 415 | .frame => unreachable, | 418 | .frame, .table => unreachable, |
| 416 | .reloc => |sym_index| .{ .addr = .{ .sym = sym_index } }, | 419 | .reloc => |sym_index| .{ .addr = .{ .sym = sym_index } }, |
| 417 | }; | 420 | }; |
| 418 | break :base &loc_buf[0]; | 421 | break :base &loc_buf[0]; |
| ... | @@ -463,13 +466,40 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -463,13 +466,40 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 463 | } | 466 | } |
| 464 | } | 467 | } |
| 465 | } | 468 | } |
| 466 | try emit.fixupRelocs(); | 469 | { |
| 467 | } | 470 | // TODO this function currently assumes all relocs via JMP/CALL instructions are 32bit in size. |
| 471 | // This should be reversed like it is done in aarch64 MIR emit code: start with the smallest | ||
| 472 | // possible resolution, i.e., 8bit, and iteratively converge on the minimum required resolution | ||
| 473 | // until the entire decl is correctly emitted with all JMP/CALL instructions within range. | ||
| 474 | for (relocs.items) |reloc| { | ||
| 475 | const target = code_offset_mapping[reloc.target]; | ||
| 476 | const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.source + reloc.length)) + reloc.target_offset; | ||
| 477 | std.mem.writeInt(i32, emit.code.items[reloc.source_offset..][0..4], @intCast(disp), .little); | ||
| 478 | } | ||
| 479 | } | ||
| 480 | if (emit.lower.mir.table.len > 0) { | ||
| 481 | if (emit.lower.bin_file.cast(.elf)) |elf_file| { | ||
| 482 | const zo = elf_file.zigObjectPtr().?; | ||
| 483 | const atom = zo.symbol(emit.atom_index).atom(elf_file).?; | ||
| 468 | 484 | ||
| 469 | pub fn deinit(emit: *Emit) void { | 485 | const ptr_size = @divExact(emit.lower.target.ptrBitWidth(), 8); |
| 470 | emit.relocs.deinit(emit.lower.allocator); | 486 | var table_offset = std.mem.alignForward(u32, @intCast(emit.code.items.len), ptr_size); |
| 471 | emit.code_offset_mapping.deinit(emit.lower.allocator); | 487 | for (table_relocs.items) |table_reloc| try atom.addReloc(gpa, .{ |
| 472 | emit.* = undefined; | 488 | .r_offset = table_reloc.source_offset, |
| 489 | .r_info = @as(u64, emit.atom_index) << 32 | @intFromEnum(std.elf.R_X86_64.@"32"), | ||
| 490 | .r_addend = @as(i64, table_offset) + table_reloc.target_offset, | ||
| 491 | }, zo); | ||
| 492 | for (emit.lower.mir.table) |entry| { | ||
| 493 | try atom.addReloc(gpa, .{ | ||
| 494 | .r_offset = table_offset, | ||
| 495 | .r_info = @as(u64, emit.atom_index) << 32 | @intFromEnum(std.elf.R_X86_64.@"64"), | ||
| 496 | .r_addend = code_offset_mapping[entry], | ||
| 497 | }, zo); | ||
| 498 | table_offset += ptr_size; | ||
| 499 | } | ||
| 500 | try emit.code.appendNTimes(gpa, 0, table_offset - emit.code.items.len); | ||
| 501 | } else unreachable; | ||
| 502 | } | ||
| 473 | } | 503 | } |
| 474 | 504 | ||
| 475 | fn fail(emit: *Emit, comptime format: []const u8, args: anytype) Error { | 505 | fn fail(emit: *Emit, comptime format: []const u8, args: anytype) Error { |
| ... | @@ -481,7 +511,7 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) Error { | ... | @@ -481,7 +511,7 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) Error { |
| 481 | 511 | ||
| 482 | const Reloc = struct { | 512 | const Reloc = struct { |
| 483 | /// Offset of the instruction. | 513 | /// Offset of the instruction. |
| 484 | source: usize, | 514 | source: u32, |
| 485 | /// Offset of the relocation within the instruction. | 515 | /// Offset of the relocation within the instruction. |
| 486 | source_offset: u32, | 516 | source_offset: u32, |
| 487 | /// Target of the relocation. | 517 | /// Target of the relocation. |
| ... | @@ -492,18 +522,12 @@ const Reloc = struct { | ... | @@ -492,18 +522,12 @@ const Reloc = struct { |
| 492 | length: u5, | 522 | length: u5, |
| 493 | }; | 523 | }; |
| 494 | 524 | ||
| 495 | fn fixupRelocs(emit: *Emit) Error!void { | 525 | const TableReloc = struct { |
| 496 | // TODO this function currently assumes all relocs via JMP/CALL instructions are 32bit in size. | 526 | /// Offset of the relocation. |
| 497 | // This should be reversed like it is done in aarch64 MIR emit code: start with the smallest | 527 | source_offset: u32, |
| 498 | // possible resolution, i.e., 8bit, and iteratively converge on the minimum required resolution | 528 | /// Offset from the start of the table. |
| 499 | // until the entire decl is correctly emitted with all JMP/CALL instructions within range. | 529 | target_offset: i32, |
| 500 | for (emit.relocs.items) |reloc| { | 530 | }; |
| 501 | const target = emit.code_offset_mapping.get(reloc.target) orelse | ||
| 502 | return emit.fail("JMP/CALL relocation target not found!", .{}); | ||
| 503 | const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.source + reloc.length)) + reloc.target_offset; | ||
| 504 | std.mem.writeInt(i32, emit.code.items[reloc.source_offset..][0..4], @intCast(disp), .little); | ||
| 505 | } | ||
| 506 | } | ||
| 507 | 531 | ||
| 508 | const Loc = struct { | 532 | const Loc = struct { |
| 509 | line: u32, | 533 | line: u32, |
src/arch/x86_64/Lower.zig+12-3| ... | @@ -57,6 +57,7 @@ pub const Reloc = struct { | ... | @@ -57,6 +57,7 @@ pub const Reloc = struct { |
| 57 | 57 | ||
| 58 | const Target = union(enum) { | 58 | const Target = union(enum) { |
| 59 | inst: Mir.Inst.Index, | 59 | inst: Mir.Inst.Index, |
| 60 | table, | ||
| 60 | linker_reloc: u32, | 61 | linker_reloc: u32, |
| 61 | linker_tlsld: u32, | 62 | linker_tlsld: u32, |
| 62 | linker_dtpoff: u32, | 63 | linker_dtpoff: u32, |
| ... | @@ -348,7 +349,7 @@ pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error { | ... | @@ -348,7 +349,7 @@ pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error { |
| 348 | return error.LowerFail; | 349 | return error.LowerFail; |
| 349 | } | 350 | } |
| 350 | 351 | ||
| 351 | pub fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate { | 352 | pub fn imm(lower: *const Lower, ops: Mir.Inst.Ops, i: u32) Immediate { |
| 352 | return switch (ops) { | 353 | return switch (ops) { |
| 353 | .rri_s, | 354 | .rri_s, |
| 354 | .ri_s, | 355 | .ri_s, |
| ... | @@ -379,8 +380,16 @@ pub fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate { | ... | @@ -379,8 +380,16 @@ pub fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate { |
| 379 | }; | 380 | }; |
| 380 | } | 381 | } |
| 381 | 382 | ||
| 382 | pub fn mem(lower: Lower, payload: u32) Memory { | 383 | pub fn mem(lower: *Lower, payload: u32) Memory { |
| 383 | return lower.mir.resolveFrameLoc(lower.mir.extraData(Mir.Memory, payload).data).decode(); | 384 | var m = lower.mir.resolveFrameLoc(lower.mir.extraData(Mir.Memory, payload).data).decode(); |
| 385 | switch (m) { | ||
| 386 | .sib => |*sib| switch (sib.base) { | ||
| 387 | else => {}, | ||
| 388 | .table => sib.disp = lower.reloc(.table, sib.disp).signed, | ||
| 389 | }, | ||
| 390 | else => {}, | ||
| 391 | } | ||
| 392 | return m; | ||
| 384 | } | 393 | } |
| 385 | 394 | ||
| 386 | fn reloc(lower: *Lower, target: Reloc.Target, off: i32) Immediate { | 395 | fn reloc(lower: *Lower, target: Reloc.Target, off: i32) Immediate { |
src/arch/x86_64/Mir.zig+6-3| ... | @@ -9,6 +9,7 @@ | ... | @@ -9,6 +9,7 @@ |
| 9 | instructions: std.MultiArrayList(Inst).Slice, | 9 | instructions: 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. |
| 11 | extra: []const u32, | 11 | extra: []const u32, |
| 12 | table: []const Inst.Index, | ||
| 12 | frame_locs: std.MultiArrayList(FrameLoc).Slice, | 13 | frame_locs: std.MultiArrayList(FrameLoc).Slice, |
| 13 | 14 | ||
| 14 | pub const Inst = struct { | 15 | pub const Inst = struct { |
| ... | @@ -1237,7 +1238,7 @@ pub const Memory = struct { | ... | @@ -1237,7 +1238,7 @@ pub const Memory = struct { |
| 1237 | size: bits.Memory.Size, | 1238 | size: bits.Memory.Size, |
| 1238 | index: Register, | 1239 | index: Register, |
| 1239 | scale: bits.Memory.Scale, | 1240 | scale: bits.Memory.Scale, |
| 1240 | _: u16 = undefined, | 1241 | _: u15 = undefined, |
| 1241 | }; | 1242 | }; |
| 1242 | 1243 | ||
| 1243 | pub fn encode(mem: bits.Memory) Memory { | 1244 | pub fn encode(mem: bits.Memory) Memory { |
| ... | @@ -1260,7 +1261,7 @@ pub const Memory = struct { | ... | @@ -1260,7 +1261,7 @@ pub const Memory = struct { |
| 1260 | }, | 1261 | }, |
| 1261 | }, | 1262 | }, |
| 1262 | .base = switch (mem.base) { | 1263 | .base = switch (mem.base) { |
| 1263 | .none => undefined, | 1264 | .none, .table => undefined, |
| 1264 | .reg => |reg| @intFromEnum(reg), | 1265 | .reg => |reg| @intFromEnum(reg), |
| 1265 | .frame => |frame_index| @intFromEnum(frame_index), | 1266 | .frame => |frame_index| @intFromEnum(frame_index), |
| 1266 | .reloc => |sym_index| sym_index, | 1267 | .reloc => |sym_index| sym_index, |
| ... | @@ -1289,6 +1290,7 @@ pub const Memory = struct { | ... | @@ -1289,6 +1290,7 @@ pub const Memory = struct { |
| 1289 | .none => .none, | 1290 | .none => .none, |
| 1290 | .reg => .{ .reg = @enumFromInt(mem.base) }, | 1291 | .reg => .{ .reg = @enumFromInt(mem.base) }, |
| 1291 | .frame => .{ .frame = @enumFromInt(mem.base) }, | 1292 | .frame => .{ .frame = @enumFromInt(mem.base) }, |
| 1293 | .table => .table, | ||
| 1292 | .reloc => .{ .reloc = mem.base }, | 1294 | .reloc => .{ .reloc = mem.base }, |
| 1293 | }, | 1295 | }, |
| 1294 | .scale_index = switch (mem.info.index) { | 1296 | .scale_index = switch (mem.info.index) { |
| ... | @@ -1317,6 +1319,7 @@ pub const Memory = struct { | ... | @@ -1317,6 +1319,7 @@ pub const Memory = struct { |
| 1317 | pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void { | 1319 | pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void { |
| 1318 | mir.instructions.deinit(gpa); | 1320 | mir.instructions.deinit(gpa); |
| 1319 | gpa.free(mir.extra); | 1321 | gpa.free(mir.extra); |
| 1322 | gpa.free(mir.table); | ||
| 1320 | mir.frame_locs.deinit(gpa); | 1323 | mir.frame_locs.deinit(gpa); |
| 1321 | mir.* = undefined; | 1324 | mir.* = undefined; |
| 1322 | } | 1325 | } |
| ... | @@ -1352,7 +1355,7 @@ pub fn resolveFrameAddr(mir: Mir, frame_addr: bits.FrameAddr) bits.RegisterOffse | ... | @@ -1352,7 +1355,7 @@ pub fn resolveFrameAddr(mir: Mir, frame_addr: bits.FrameAddr) bits.RegisterOffse |
| 1352 | 1355 | ||
| 1353 | pub fn resolveFrameLoc(mir: Mir, mem: Memory) Memory { | 1356 | pub fn resolveFrameLoc(mir: Mir, mem: Memory) Memory { |
| 1354 | return switch (mem.info.base) { | 1357 | return switch (mem.info.base) { |
| 1355 | .none, .reg, .reloc => mem, | 1358 | .none, .reg, .table, .reloc => mem, |
| 1356 | .frame => if (mir.frame_locs.len > 0) .{ | 1359 | .frame => if (mir.frame_locs.len > 0) .{ |
| 1357 | .info = .{ | 1360 | .info = .{ |
| 1358 | .base = .reg, | 1361 | .base = .reg, |
src/arch/x86_64/bits.zig+3-2| ... | @@ -482,17 +482,18 @@ pub const Memory = struct { | ... | @@ -482,17 +482,18 @@ pub const Memory = struct { |
| 482 | base: Base = .none, | 482 | base: Base = .none, |
| 483 | mod: Mod = .{ .rm = .{} }, | 483 | mod: Mod = .{ .rm = .{} }, |
| 484 | 484 | ||
| 485 | pub const Base = union(enum(u2)) { | 485 | pub const Base = union(enum(u3)) { |
| 486 | none, | 486 | none, |
| 487 | reg: Register, | 487 | reg: Register, |
| 488 | frame: FrameIndex, | 488 | frame: FrameIndex, |
| 489 | table, | ||
| 489 | reloc: u32, | 490 | reloc: u32, |
| 490 | 491 | ||
| 491 | pub const Tag = @typeInfo(Base).@"union".tag_type.?; | 492 | pub const Tag = @typeInfo(Base).@"union".tag_type.?; |
| 492 | 493 | ||
| 493 | pub fn isExtended(self: Base) bool { | 494 | pub fn isExtended(self: Base) bool { |
| 494 | return switch (self) { | 495 | return switch (self) { |
| 495 | .none, .frame, .reloc => false, // rsp, rbp, and rip are not extended | 496 | .none, .frame, .table, .reloc => false, // rsp, rbp, and rip are not extended |
| 496 | .reg => |reg| reg.isExtended(), | 497 | .reg => |reg| reg.isExtended(), |
| 497 | }; | 498 | }; |
| 498 | } | 499 | } |
src/arch/x86_64/encoder.zig+52-51| ... | @@ -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, .reloc => false, | 141 | .none, .frame, .table, .reloc => false, |
| 142 | .reg => |reg| reg.class() == .segment, | 142 | .reg => |reg| reg.class() == .segment, |
| 143 | }, | 143 | }, |
| 144 | }; | 144 | }; |
| ... | @@ -161,9 +161,9 @@ pub const Instruction = struct { | ... | @@ -161,9 +161,9 @@ pub const Instruction = struct { |
| 161 | 161 | ||
| 162 | pub fn disp(mem: Memory) Immediate { | 162 | pub fn disp(mem: Memory) Immediate { |
| 163 | return switch (mem) { | 163 | return switch (mem) { |
| 164 | .sib => |s| Immediate.s(s.disp), | 164 | .sib => |s| .s(s.disp), |
| 165 | .rip => |r| Immediate.s(r.disp), | 165 | .rip => |r| .s(r.disp), |
| 166 | .moffs => |m| Immediate.u(m.offset), | 166 | .moffs => |m| .u(m.offset), |
| 167 | }; | 167 | }; |
| 168 | } | 168 | } |
| 169 | 169 | ||
| ... | @@ -277,6 +277,7 @@ pub const Instruction = struct { | ... | @@ -277,6 +277,7 @@ pub const Instruction = struct { |
| 277 | .none => any = false, | 277 | .none => any = false, |
| 278 | .reg => |reg| try writer.print("{s}", .{@tagName(reg)}), | 278 | .reg => |reg| try writer.print("{s}", .{@tagName(reg)}), |
| 279 | .frame => |frame_index| try writer.print("{}", .{frame_index}), | 279 | .frame => |frame_index| try writer.print("{}", .{frame_index}), |
| 280 | .table => try writer.print("Table", .{}), | ||
| 280 | .reloc => |sym_index| try writer.print("Symbol({d})", .{sym_index}), | 281 | .reloc => |sym_index| try writer.print("Symbol({d})", .{sym_index}), |
| 281 | } | 282 | } |
| 282 | if (mem.scaleIndex()) |si| { | 283 | if (mem.scaleIndex()) |si| { |
| ... | @@ -614,7 +615,7 @@ pub const Instruction = struct { | ... | @@ -614,7 +615,7 @@ pub const Instruction = struct { |
| 614 | switch (mem) { | 615 | switch (mem) { |
| 615 | .moffs => unreachable, | 616 | .moffs => unreachable, |
| 616 | .sib => |sib| switch (sib.base) { | 617 | .sib => |sib| switch (sib.base) { |
| 617 | .none => { | 618 | .none, .table => { |
| 618 | try encoder.modRm_SIBDisp0(operand_enc); | 619 | try encoder.modRm_SIBDisp0(operand_enc); |
| 619 | if (mem.scaleIndex()) |si| { | 620 | if (mem.scaleIndex()) |si| { |
| 620 | const scale = math.log2_int(u4, si.scale); | 621 | const scale = math.log2_int(u4, si.scale); |
| ... | @@ -1191,7 +1192,7 @@ const TestEncode = struct { | ... | @@ -1191,7 +1192,7 @@ const TestEncode = struct { |
| 1191 | ) !void { | 1192 | ) !void { |
| 1192 | var stream = std.io.fixedBufferStream(&enc.buffer); | 1193 | var stream = std.io.fixedBufferStream(&enc.buffer); |
| 1193 | var count_writer = std.io.countingWriter(stream.writer()); | 1194 | var count_writer = std.io.countingWriter(stream.writer()); |
| 1194 | const inst = try Instruction.new(.none, mnemonic, ops); | 1195 | const inst: Instruction = try .new(.none, mnemonic, ops); |
| 1195 | try inst.encode(count_writer.writer(), .{}); | 1196 | try inst.encode(count_writer.writer(), .{}); |
| 1196 | enc.index = count_writer.bytes_written; | 1197 | enc.index = count_writer.bytes_written; |
| 1197 | } | 1198 | } |
| ... | @@ -1205,9 +1206,9 @@ test "encode" { | ... | @@ -1205,9 +1206,9 @@ test "encode" { |
| 1205 | var buf = std.ArrayList(u8).init(testing.allocator); | 1206 | var buf = std.ArrayList(u8).init(testing.allocator); |
| 1206 | defer buf.deinit(); | 1207 | defer buf.deinit(); |
| 1207 | 1208 | ||
| 1208 | const inst = try Instruction.new(.none, .mov, &.{ | 1209 | const inst: Instruction = try .new(.none, .mov, &.{ |
| 1209 | .{ .reg = .rbx }, | 1210 | .{ .reg = .rbx }, |
| 1210 | .{ .imm = Instruction.Immediate.u(4) }, | 1211 | .{ .imm = .u(4) }, |
| 1211 | }); | 1212 | }); |
| 1212 | try inst.encode(buf.writer(), .{}); | 1213 | try inst.encode(buf.writer(), .{}); |
| 1213 | try testing.expectEqualSlices(u8, &.{ 0x48, 0xc7, 0xc3, 0x4, 0x0, 0x0, 0x0 }, buf.items); | 1214 | try testing.expectEqualSlices(u8, &.{ 0x48, 0xc7, 0xc3, 0x4, 0x0, 0x0, 0x0 }, buf.items); |
| ... | @@ -1217,47 +1218,47 @@ test "lower I encoding" { | ... | @@ -1217,47 +1218,47 @@ test "lower I encoding" { |
| 1217 | var enc = TestEncode{}; | 1218 | var enc = TestEncode{}; |
| 1218 | 1219 | ||
| 1219 | try enc.encode(.push, &.{ | 1220 | try enc.encode(.push, &.{ |
| 1220 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1221 | .{ .imm = .u(0x10) }, |
| 1221 | }); | 1222 | }); |
| 1222 | try expectEqualHexStrings("\x6A\x10", enc.code(), "push 0x10"); | 1223 | try expectEqualHexStrings("\x6A\x10", enc.code(), "push 0x10"); |
| 1223 | 1224 | ||
| 1224 | try enc.encode(.push, &.{ | 1225 | try enc.encode(.push, &.{ |
| 1225 | .{ .imm = Instruction.Immediate.u(0x1000) }, | 1226 | .{ .imm = .u(0x1000) }, |
| 1226 | }); | 1227 | }); |
| 1227 | try expectEqualHexStrings("\x66\x68\x00\x10", enc.code(), "push 0x1000"); | 1228 | try expectEqualHexStrings("\x66\x68\x00\x10", enc.code(), "push 0x1000"); |
| 1228 | 1229 | ||
| 1229 | try enc.encode(.push, &.{ | 1230 | try enc.encode(.push, &.{ |
| 1230 | .{ .imm = Instruction.Immediate.u(0x10000000) }, | 1231 | .{ .imm = .u(0x10000000) }, |
| 1231 | }); | 1232 | }); |
| 1232 | try expectEqualHexStrings("\x68\x00\x00\x00\x10", enc.code(), "push 0x10000000"); | 1233 | try expectEqualHexStrings("\x68\x00\x00\x00\x10", enc.code(), "push 0x10000000"); |
| 1233 | 1234 | ||
| 1234 | try enc.encode(.adc, &.{ | 1235 | try enc.encode(.adc, &.{ |
| 1235 | .{ .reg = .rax }, | 1236 | .{ .reg = .rax }, |
| 1236 | .{ .imm = Instruction.Immediate.u(0x10000000) }, | 1237 | .{ .imm = .u(0x10000000) }, |
| 1237 | }); | 1238 | }); |
| 1238 | try expectEqualHexStrings("\x48\x15\x00\x00\x00\x10", enc.code(), "adc rax, 0x10000000"); | 1239 | try expectEqualHexStrings("\x48\x15\x00\x00\x00\x10", enc.code(), "adc rax, 0x10000000"); |
| 1239 | 1240 | ||
| 1240 | try enc.encode(.add, &.{ | 1241 | try enc.encode(.add, &.{ |
| 1241 | .{ .reg = .al }, | 1242 | .{ .reg = .al }, |
| 1242 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1243 | .{ .imm = .u(0x10) }, |
| 1243 | }); | 1244 | }); |
| 1244 | try expectEqualHexStrings("\x04\x10", enc.code(), "add al, 0x10"); | 1245 | try expectEqualHexStrings("\x04\x10", enc.code(), "add al, 0x10"); |
| 1245 | 1246 | ||
| 1246 | try enc.encode(.add, &.{ | 1247 | try enc.encode(.add, &.{ |
| 1247 | .{ .reg = .rax }, | 1248 | .{ .reg = .rax }, |
| 1248 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1249 | .{ .imm = .u(0x10) }, |
| 1249 | }); | 1250 | }); |
| 1250 | try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10"); | 1251 | try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10"); |
| 1251 | 1252 | ||
| 1252 | try enc.encode(.sbb, &.{ | 1253 | try enc.encode(.sbb, &.{ |
| 1253 | .{ .reg = .ax }, | 1254 | .{ .reg = .ax }, |
| 1254 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1255 | .{ .imm = .u(0x10) }, |
| 1255 | }); | 1256 | }); |
| 1256 | try expectEqualHexStrings("\x66\x1D\x10\x00", enc.code(), "sbb ax, 0x10"); | 1257 | try expectEqualHexStrings("\x66\x1D\x10\x00", enc.code(), "sbb ax, 0x10"); |
| 1257 | 1258 | ||
| 1258 | try enc.encode(.xor, &.{ | 1259 | try enc.encode(.xor, &.{ |
| 1259 | .{ .reg = .al }, | 1260 | .{ .reg = .al }, |
| 1260 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1261 | .{ .imm = .u(0x10) }, |
| 1261 | }); | 1262 | }); |
| 1262 | try expectEqualHexStrings("\x34\x10", enc.code(), "xor al, 0x10"); | 1263 | try expectEqualHexStrings("\x34\x10", enc.code(), "xor al, 0x10"); |
| 1263 | } | 1264 | } |
| ... | @@ -1267,43 +1268,43 @@ test "lower MI encoding" { | ... | @@ -1267,43 +1268,43 @@ test "lower MI encoding" { |
| 1267 | 1268 | ||
| 1268 | try enc.encode(.mov, &.{ | 1269 | try enc.encode(.mov, &.{ |
| 1269 | .{ .reg = .r12 }, | 1270 | .{ .reg = .r12 }, |
| 1270 | .{ .imm = Instruction.Immediate.u(0x1000) }, | 1271 | .{ .imm = .u(0x1000) }, |
| 1271 | }); | 1272 | }); |
| 1272 | try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000"); | 1273 | try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000"); |
| 1273 | 1274 | ||
| 1274 | try enc.encode(.mov, &.{ | 1275 | try enc.encode(.mov, &.{ |
| 1275 | .{ .mem = Instruction.Memory.initSib(.byte, .{ .base = .{ .reg = .r12 } }) }, | 1276 | .{ .mem = Instruction.Memory.initSib(.byte, .{ .base = .{ .reg = .r12 } }) }, |
| 1276 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1277 | .{ .imm = .u(0x10) }, |
| 1277 | }); | 1278 | }); |
| 1278 | try expectEqualHexStrings("\x41\xC6\x04\x24\x10", enc.code(), "mov BYTE PTR [r12], 0x10"); | 1279 | try expectEqualHexStrings("\x41\xC6\x04\x24\x10", enc.code(), "mov BYTE PTR [r12], 0x10"); |
| 1279 | 1280 | ||
| 1280 | try enc.encode(.mov, &.{ | 1281 | try enc.encode(.mov, &.{ |
| 1281 | .{ .reg = .r12 }, | 1282 | .{ .reg = .r12 }, |
| 1282 | .{ .imm = Instruction.Immediate.u(0x1000) }, | 1283 | .{ .imm = .u(0x1000) }, |
| 1283 | }); | 1284 | }); |
| 1284 | try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000"); | 1285 | try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000"); |
| 1285 | 1286 | ||
| 1286 | try enc.encode(.mov, &.{ | 1287 | try enc.encode(.mov, &.{ |
| 1287 | .{ .reg = .r12 }, | 1288 | .{ .reg = .r12 }, |
| 1288 | .{ .imm = Instruction.Immediate.u(0x1000) }, | 1289 | .{ .imm = .u(0x1000) }, |
| 1289 | }); | 1290 | }); |
| 1290 | try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000"); | 1291 | try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000"); |
| 1291 | 1292 | ||
| 1292 | try enc.encode(.mov, &.{ | 1293 | try enc.encode(.mov, &.{ |
| 1293 | .{ .reg = .rax }, | 1294 | .{ .reg = .rax }, |
| 1294 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1295 | .{ .imm = .u(0x10) }, |
| 1295 | }); | 1296 | }); |
| 1296 | try expectEqualHexStrings("\x48\xc7\xc0\x10\x00\x00\x00", enc.code(), "mov rax, 0x10"); | 1297 | try expectEqualHexStrings("\x48\xc7\xc0\x10\x00\x00\x00", enc.code(), "mov rax, 0x10"); |
| 1297 | 1298 | ||
| 1298 | try enc.encode(.mov, &.{ | 1299 | try enc.encode(.mov, &.{ |
| 1299 | .{ .mem = Instruction.Memory.initSib(.dword, .{ .base = .{ .reg = .r11 } }) }, | 1300 | .{ .mem = Instruction.Memory.initSib(.dword, .{ .base = .{ .reg = .r11 } }) }, |
| 1300 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1301 | .{ .imm = .u(0x10) }, |
| 1301 | }); | 1302 | }); |
| 1302 | try expectEqualHexStrings("\x41\xc7\x03\x10\x00\x00\x00", enc.code(), "mov DWORD PTR [r11], 0x10"); | 1303 | try expectEqualHexStrings("\x41\xc7\x03\x10\x00\x00\x00", enc.code(), "mov DWORD PTR [r11], 0x10"); |
| 1303 | 1304 | ||
| 1304 | try enc.encode(.mov, &.{ | 1305 | try enc.encode(.mov, &.{ |
| 1305 | .{ .mem = Instruction.Memory.initRip(.qword, 0x10) }, | 1306 | .{ .mem = Instruction.Memory.initRip(.qword, 0x10) }, |
| 1306 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1307 | .{ .imm = .u(0x10) }, |
| 1307 | }); | 1308 | }); |
| 1308 | try expectEqualHexStrings( | 1309 | try expectEqualHexStrings( |
| 1309 | "\x48\xC7\x05\x10\x00\x00\x00\x10\x00\x00\x00", | 1310 | "\x48\xC7\x05\x10\x00\x00\x00\x10\x00\x00\x00", |
| ... | @@ -1313,19 +1314,19 @@ test "lower MI encoding" { | ... | @@ -1313,19 +1314,19 @@ test "lower MI encoding" { |
| 1313 | 1314 | ||
| 1314 | try enc.encode(.mov, &.{ | 1315 | try enc.encode(.mov, &.{ |
| 1315 | .{ .mem = Instruction.Memory.initSib(.qword, .{ .base = .{ .reg = .rbp }, .disp = -8 }) }, | 1316 | .{ .mem = Instruction.Memory.initSib(.qword, .{ .base = .{ .reg = .rbp }, .disp = -8 }) }, |
| 1316 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1317 | .{ .imm = .u(0x10) }, |
| 1317 | }); | 1318 | }); |
| 1318 | try expectEqualHexStrings("\x48\xc7\x45\xf8\x10\x00\x00\x00", enc.code(), "mov QWORD PTR [rbp - 8], 0x10"); | 1319 | try expectEqualHexStrings("\x48\xc7\x45\xf8\x10\x00\x00\x00", enc.code(), "mov QWORD PTR [rbp - 8], 0x10"); |
| 1319 | 1320 | ||
| 1320 | try enc.encode(.mov, &.{ | 1321 | try enc.encode(.mov, &.{ |
| 1321 | .{ .mem = Instruction.Memory.initSib(.word, .{ .base = .{ .reg = .rbp }, .disp = -2 }) }, | 1322 | .{ .mem = Instruction.Memory.initSib(.word, .{ .base = .{ .reg = .rbp }, .disp = -2 }) }, |
| 1322 | .{ .imm = Instruction.Immediate.s(-16) }, | 1323 | .{ .imm = .s(-16) }, |
| 1323 | }); | 1324 | }); |
| 1324 | try expectEqualHexStrings("\x66\xC7\x45\xFE\xF0\xFF", enc.code(), "mov WORD PTR [rbp - 2], -16"); | 1325 | try expectEqualHexStrings("\x66\xC7\x45\xFE\xF0\xFF", enc.code(), "mov WORD PTR [rbp - 2], -16"); |
| 1325 | 1326 | ||
| 1326 | try enc.encode(.mov, &.{ | 1327 | try enc.encode(.mov, &.{ |
| 1327 | .{ .mem = Instruction.Memory.initSib(.byte, .{ .base = .{ .reg = .rbp }, .disp = -1 }) }, | 1328 | .{ .mem = Instruction.Memory.initSib(.byte, .{ .base = .{ .reg = .rbp }, .disp = -1 }) }, |
| 1328 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1329 | .{ .imm = .u(0x10) }, |
| 1329 | }); | 1330 | }); |
| 1330 | try expectEqualHexStrings("\xC6\x45\xFF\x10", enc.code(), "mov BYTE PTR [rbp - 1], 0x10"); | 1331 | try expectEqualHexStrings("\xC6\x45\xFF\x10", enc.code(), "mov BYTE PTR [rbp - 1], 0x10"); |
| 1331 | 1332 | ||
| ... | @@ -1335,7 +1336,7 @@ test "lower MI encoding" { | ... | @@ -1335,7 +1336,7 @@ test "lower MI encoding" { |
| 1335 | .disp = 0x10000000, | 1336 | .disp = 0x10000000, |
| 1336 | .scale_index = .{ .scale = 2, .index = .rcx }, | 1337 | .scale_index = .{ .scale = 2, .index = .rcx }, |
| 1337 | }) }, | 1338 | }) }, |
| 1338 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1339 | .{ .imm = .u(0x10) }, |
| 1339 | }); | 1340 | }); |
| 1340 | try expectEqualHexStrings( | 1341 | try expectEqualHexStrings( |
| 1341 | "\x48\xC7\x04\x4D\x00\x00\x00\x10\x10\x00\x00\x00", | 1342 | "\x48\xC7\x04\x4D\x00\x00\x00\x10\x10\x00\x00\x00", |
| ... | @@ -1345,43 +1346,43 @@ test "lower MI encoding" { | ... | @@ -1345,43 +1346,43 @@ test "lower MI encoding" { |
| 1345 | 1346 | ||
| 1346 | try enc.encode(.adc, &.{ | 1347 | try enc.encode(.adc, &.{ |
| 1347 | .{ .mem = Instruction.Memory.initSib(.byte, .{ .base = .{ .reg = .rbp }, .disp = -0x10 }) }, | 1348 | .{ .mem = Instruction.Memory.initSib(.byte, .{ .base = .{ .reg = .rbp }, .disp = -0x10 }) }, |
| 1348 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1349 | .{ .imm = .u(0x10) }, |
| 1349 | }); | 1350 | }); |
| 1350 | try expectEqualHexStrings("\x80\x55\xF0\x10", enc.code(), "adc BYTE PTR [rbp - 0x10], 0x10"); | 1351 | try expectEqualHexStrings("\x80\x55\xF0\x10", enc.code(), "adc BYTE PTR [rbp - 0x10], 0x10"); |
| 1351 | 1352 | ||
| 1352 | try enc.encode(.adc, &.{ | 1353 | try enc.encode(.adc, &.{ |
| 1353 | .{ .mem = Instruction.Memory.initRip(.qword, 0) }, | 1354 | .{ .mem = Instruction.Memory.initRip(.qword, 0) }, |
| 1354 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1355 | .{ .imm = .u(0x10) }, |
| 1355 | }); | 1356 | }); |
| 1356 | try expectEqualHexStrings("\x48\x83\x15\x00\x00\x00\x00\x10", enc.code(), "adc QWORD PTR [rip], 0x10"); | 1357 | try expectEqualHexStrings("\x48\x83\x15\x00\x00\x00\x00\x10", enc.code(), "adc QWORD PTR [rip], 0x10"); |
| 1357 | 1358 | ||
| 1358 | try enc.encode(.adc, &.{ | 1359 | try enc.encode(.adc, &.{ |
| 1359 | .{ .reg = .rax }, | 1360 | .{ .reg = .rax }, |
| 1360 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1361 | .{ .imm = .u(0x10) }, |
| 1361 | }); | 1362 | }); |
| 1362 | try expectEqualHexStrings("\x48\x83\xD0\x10", enc.code(), "adc rax, 0x10"); | 1363 | try expectEqualHexStrings("\x48\x83\xD0\x10", enc.code(), "adc rax, 0x10"); |
| 1363 | 1364 | ||
| 1364 | try enc.encode(.add, &.{ | 1365 | try enc.encode(.add, &.{ |
| 1365 | .{ .mem = Instruction.Memory.initSib(.dword, .{ .base = .{ .reg = .rdx }, .disp = -8 }) }, | 1366 | .{ .mem = Instruction.Memory.initSib(.dword, .{ .base = .{ .reg = .rdx }, .disp = -8 }) }, |
| 1366 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1367 | .{ .imm = .u(0x10) }, |
| 1367 | }); | 1368 | }); |
| 1368 | try expectEqualHexStrings("\x83\x42\xF8\x10", enc.code(), "add DWORD PTR [rdx - 8], 0x10"); | 1369 | try expectEqualHexStrings("\x83\x42\xF8\x10", enc.code(), "add DWORD PTR [rdx - 8], 0x10"); |
| 1369 | 1370 | ||
| 1370 | try enc.encode(.add, &.{ | 1371 | try enc.encode(.add, &.{ |
| 1371 | .{ .reg = .rax }, | 1372 | .{ .reg = .rax }, |
| 1372 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1373 | .{ .imm = .u(0x10) }, |
| 1373 | }); | 1374 | }); |
| 1374 | try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10"); | 1375 | try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10"); |
| 1375 | 1376 | ||
| 1376 | try enc.encode(.add, &.{ | 1377 | try enc.encode(.add, &.{ |
| 1377 | .{ .mem = Instruction.Memory.initSib(.qword, .{ .base = .{ .reg = .rbp }, .disp = -0x10 }) }, | 1378 | .{ .mem = Instruction.Memory.initSib(.qword, .{ .base = .{ .reg = .rbp }, .disp = -0x10 }) }, |
| 1378 | .{ .imm = Instruction.Immediate.s(-0x10) }, | 1379 | .{ .imm = .s(-0x10) }, |
| 1379 | }); | 1380 | }); |
| 1380 | try expectEqualHexStrings("\x48\x83\x45\xF0\xF0", enc.code(), "add QWORD PTR [rbp - 0x10], -0x10"); | 1381 | try expectEqualHexStrings("\x48\x83\x45\xF0\xF0", enc.code(), "add QWORD PTR [rbp - 0x10], -0x10"); |
| 1381 | 1382 | ||
| 1382 | try enc.encode(.@"and", &.{ | 1383 | try enc.encode(.@"and", &.{ |
| 1383 | .{ .mem = Instruction.Memory.initSib(.dword, .{ .base = .{ .reg = .ds }, .disp = 0x10000000 }) }, | 1384 | .{ .mem = Instruction.Memory.initSib(.dword, .{ .base = .{ .reg = .ds }, .disp = 0x10000000 }) }, |
| 1384 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1385 | .{ .imm = .u(0x10) }, |
| 1385 | }); | 1386 | }); |
| 1386 | try expectEqualHexStrings( | 1387 | try expectEqualHexStrings( |
| 1387 | "\x83\x24\x25\x00\x00\x00\x10\x10", | 1388 | "\x83\x24\x25\x00\x00\x00\x10\x10", |
| ... | @@ -1391,7 +1392,7 @@ test "lower MI encoding" { | ... | @@ -1391,7 +1392,7 @@ test "lower MI encoding" { |
| 1391 | 1392 | ||
| 1392 | try enc.encode(.@"and", &.{ | 1393 | try enc.encode(.@"and", &.{ |
| 1393 | .{ .mem = Instruction.Memory.initSib(.dword, .{ .base = .{ .reg = .es }, .disp = 0x10000000 }) }, | 1394 | .{ .mem = Instruction.Memory.initSib(.dword, .{ .base = .{ .reg = .es }, .disp = 0x10000000 }) }, |
| 1394 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1395 | .{ .imm = .u(0x10) }, |
| 1395 | }); | 1396 | }); |
| 1396 | try expectEqualHexStrings( | 1397 | try expectEqualHexStrings( |
| 1397 | "\x26\x83\x24\x25\x00\x00\x00\x10\x10", | 1398 | "\x26\x83\x24\x25\x00\x00\x00\x10\x10", |
| ... | @@ -1401,7 +1402,7 @@ test "lower MI encoding" { | ... | @@ -1401,7 +1402,7 @@ test "lower MI encoding" { |
| 1401 | 1402 | ||
| 1402 | try enc.encode(.@"and", &.{ | 1403 | try enc.encode(.@"and", &.{ |
| 1403 | .{ .mem = Instruction.Memory.initSib(.dword, .{ .base = .{ .reg = .r12 }, .disp = 0x10000000 }) }, | 1404 | .{ .mem = Instruction.Memory.initSib(.dword, .{ .base = .{ .reg = .r12 }, .disp = 0x10000000 }) }, |
| 1404 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1405 | .{ .imm = .u(0x10) }, |
| 1405 | }); | 1406 | }); |
| 1406 | try expectEqualHexStrings( | 1407 | try expectEqualHexStrings( |
| 1407 | "\x41\x83\xA4\x24\x00\x00\x00\x10\x10", | 1408 | "\x41\x83\xA4\x24\x00\x00\x00\x10\x10", |
| ... | @@ -1411,7 +1412,7 @@ test "lower MI encoding" { | ... | @@ -1411,7 +1412,7 @@ test "lower MI encoding" { |
| 1411 | 1412 | ||
| 1412 | try enc.encode(.sub, &.{ | 1413 | try enc.encode(.sub, &.{ |
| 1413 | .{ .mem = Instruction.Memory.initSib(.dword, .{ .base = .{ .reg = .r11 }, .disp = 0x10000000 }) }, | 1414 | .{ .mem = Instruction.Memory.initSib(.dword, .{ .base = .{ .reg = .r11 }, .disp = 0x10000000 }) }, |
| 1414 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1415 | .{ .imm = .u(0x10) }, |
| 1415 | }); | 1416 | }); |
| 1416 | try expectEqualHexStrings( | 1417 | try expectEqualHexStrings( |
| 1417 | "\x41\x83\xAB\x00\x00\x00\x10\x10", | 1418 | "\x41\x83\xAB\x00\x00\x00\x10\x10", |
| ... | @@ -1630,14 +1631,14 @@ test "lower RMI encoding" { | ... | @@ -1630,14 +1631,14 @@ test "lower RMI encoding" { |
| 1630 | try enc.encode(.imul, &.{ | 1631 | try enc.encode(.imul, &.{ |
| 1631 | .{ .reg = .r11 }, | 1632 | .{ .reg = .r11 }, |
| 1632 | .{ .reg = .r12 }, | 1633 | .{ .reg = .r12 }, |
| 1633 | .{ .imm = Instruction.Immediate.s(-2) }, | 1634 | .{ .imm = .s(-2) }, |
| 1634 | }); | 1635 | }); |
| 1635 | try expectEqualHexStrings("\x4D\x6B\xDC\xFE", enc.code(), "imul r11, r12, -2"); | 1636 | try expectEqualHexStrings("\x4D\x6B\xDC\xFE", enc.code(), "imul r11, r12, -2"); |
| 1636 | 1637 | ||
| 1637 | try enc.encode(.imul, &.{ | 1638 | try enc.encode(.imul, &.{ |
| 1638 | .{ .reg = .r11 }, | 1639 | .{ .reg = .r11 }, |
| 1639 | .{ .mem = Instruction.Memory.initRip(.qword, -16) }, | 1640 | .{ .mem = Instruction.Memory.initRip(.qword, -16) }, |
| 1640 | .{ .imm = Instruction.Immediate.s(-1024) }, | 1641 | .{ .imm = .s(-1024) }, |
| 1641 | }); | 1642 | }); |
| 1642 | try expectEqualHexStrings( | 1643 | try expectEqualHexStrings( |
| 1643 | "\x4C\x69\x1D\xF0\xFF\xFF\xFF\x00\xFC\xFF\xFF", | 1644 | "\x4C\x69\x1D\xF0\xFF\xFF\xFF\x00\xFC\xFF\xFF", |
| ... | @@ -1648,7 +1649,7 @@ test "lower RMI encoding" { | ... | @@ -1648,7 +1649,7 @@ test "lower RMI encoding" { |
| 1648 | try enc.encode(.imul, &.{ | 1649 | try enc.encode(.imul, &.{ |
| 1649 | .{ .reg = .bx }, | 1650 | .{ .reg = .bx }, |
| 1650 | .{ .mem = Instruction.Memory.initSib(.word, .{ .base = .{ .reg = .rbp }, .disp = -16 }) }, | 1651 | .{ .mem = Instruction.Memory.initSib(.word, .{ .base = .{ .reg = .rbp }, .disp = -16 }) }, |
| 1651 | .{ .imm = Instruction.Immediate.s(-1024) }, | 1652 | .{ .imm = .s(-1024) }, |
| 1652 | }); | 1653 | }); |
| 1653 | try expectEqualHexStrings( | 1654 | try expectEqualHexStrings( |
| 1654 | "\x66\x69\x5D\xF0\x00\xFC", | 1655 | "\x66\x69\x5D\xF0\x00\xFC", |
| ... | @@ -1659,7 +1660,7 @@ test "lower RMI encoding" { | ... | @@ -1659,7 +1660,7 @@ test "lower RMI encoding" { |
| 1659 | try enc.encode(.imul, &.{ | 1660 | try enc.encode(.imul, &.{ |
| 1660 | .{ .reg = .bx }, | 1661 | .{ .reg = .bx }, |
| 1661 | .{ .mem = Instruction.Memory.initSib(.word, .{ .base = .{ .reg = .rbp }, .disp = -16 }) }, | 1662 | .{ .mem = Instruction.Memory.initSib(.word, .{ .base = .{ .reg = .rbp }, .disp = -16 }) }, |
| 1662 | .{ .imm = Instruction.Immediate.u(1024) }, | 1663 | .{ .imm = .u(1024) }, |
| 1663 | }); | 1664 | }); |
| 1664 | try expectEqualHexStrings( | 1665 | try expectEqualHexStrings( |
| 1665 | "\x66\x69\x5D\xF0\x00\x04", | 1666 | "\x66\x69\x5D\xF0\x00\x04", |
| ... | @@ -1775,7 +1776,7 @@ test "lower M encoding" { | ... | @@ -1775,7 +1776,7 @@ test "lower M encoding" { |
| 1775 | try expectEqualHexStrings("\x65\xFF\x14\x25\x00\x00\x00\x00", enc.code(), "call gs:0x0"); | 1776 | try expectEqualHexStrings("\x65\xFF\x14\x25\x00\x00\x00\x00", enc.code(), "call gs:0x0"); |
| 1776 | 1777 | ||
| 1777 | try enc.encode(.call, &.{ | 1778 | try enc.encode(.call, &.{ |
| 1778 | .{ .imm = Instruction.Immediate.s(0) }, | 1779 | .{ .imm = .s(0) }, |
| 1779 | }); | 1780 | }); |
| 1780 | try expectEqualHexStrings("\xE8\x00\x00\x00\x00", enc.code(), "call 0x0"); | 1781 | try expectEqualHexStrings("\xE8\x00\x00\x00\x00", enc.code(), "call 0x0"); |
| 1781 | 1782 | ||
| ... | @@ -1834,7 +1835,7 @@ test "lower OI encoding" { | ... | @@ -1834,7 +1835,7 @@ test "lower OI encoding" { |
| 1834 | 1835 | ||
| 1835 | try enc.encode(.mov, &.{ | 1836 | try enc.encode(.mov, &.{ |
| 1836 | .{ .reg = .rax }, | 1837 | .{ .reg = .rax }, |
| 1837 | .{ .imm = Instruction.Immediate.u(0x1000000000000000) }, | 1838 | .{ .imm = .u(0x1000000000000000) }, |
| 1838 | }); | 1839 | }); |
| 1839 | try expectEqualHexStrings( | 1840 | try expectEqualHexStrings( |
| 1840 | "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x10", | 1841 | "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x10", |
| ... | @@ -1844,7 +1845,7 @@ test "lower OI encoding" { | ... | @@ -1844,7 +1845,7 @@ test "lower OI encoding" { |
| 1844 | 1845 | ||
| 1845 | try enc.encode(.mov, &.{ | 1846 | try enc.encode(.mov, &.{ |
| 1846 | .{ .reg = .r11 }, | 1847 | .{ .reg = .r11 }, |
| 1847 | .{ .imm = Instruction.Immediate.u(0x1000000000000000) }, | 1848 | .{ .imm = .u(0x1000000000000000) }, |
| 1848 | }); | 1849 | }); |
| 1849 | try expectEqualHexStrings( | 1850 | try expectEqualHexStrings( |
| 1850 | "\x49\xBB\x00\x00\x00\x00\x00\x00\x00\x10", | 1851 | "\x49\xBB\x00\x00\x00\x00\x00\x00\x00\x10", |
| ... | @@ -1854,19 +1855,19 @@ test "lower OI encoding" { | ... | @@ -1854,19 +1855,19 @@ test "lower OI encoding" { |
| 1854 | 1855 | ||
| 1855 | try enc.encode(.mov, &.{ | 1856 | try enc.encode(.mov, &.{ |
| 1856 | .{ .reg = .r11d }, | 1857 | .{ .reg = .r11d }, |
| 1857 | .{ .imm = Instruction.Immediate.u(0x10000000) }, | 1858 | .{ .imm = .u(0x10000000) }, |
| 1858 | }); | 1859 | }); |
| 1859 | try expectEqualHexStrings("\x41\xBB\x00\x00\x00\x10", enc.code(), "mov r11d, 0x10000000"); | 1860 | try expectEqualHexStrings("\x41\xBB\x00\x00\x00\x10", enc.code(), "mov r11d, 0x10000000"); |
| 1860 | 1861 | ||
| 1861 | try enc.encode(.mov, &.{ | 1862 | try enc.encode(.mov, &.{ |
| 1862 | .{ .reg = .r11w }, | 1863 | .{ .reg = .r11w }, |
| 1863 | .{ .imm = Instruction.Immediate.u(0x1000) }, | 1864 | .{ .imm = .u(0x1000) }, |
| 1864 | }); | 1865 | }); |
| 1865 | try expectEqualHexStrings("\x66\x41\xBB\x00\x10", enc.code(), "mov r11w, 0x1000"); | 1866 | try expectEqualHexStrings("\x66\x41\xBB\x00\x10", enc.code(), "mov r11w, 0x1000"); |
| 1866 | 1867 | ||
| 1867 | try enc.encode(.mov, &.{ | 1868 | try enc.encode(.mov, &.{ |
| 1868 | .{ .reg = .r11b }, | 1869 | .{ .reg = .r11b }, |
| 1869 | .{ .imm = Instruction.Immediate.u(0x10) }, | 1870 | .{ .imm = .u(0x10) }, |
| 1870 | }); | 1871 | }); |
| 1871 | try expectEqualHexStrings("\x41\xB3\x10", enc.code(), "mov r11b, 0x10"); | 1872 | try expectEqualHexStrings("\x41\xB3\x10", enc.code(), "mov r11b, 0x10"); |
| 1872 | } | 1873 | } |
| ... | @@ -1940,7 +1941,7 @@ test "lower NP encoding" { | ... | @@ -1940,7 +1941,7 @@ test "lower NP encoding" { |
| 1940 | } | 1941 | } |
| 1941 | 1942 | ||
| 1942 | fn invalidInstruction(mnemonic: Instruction.Mnemonic, ops: []const Instruction.Operand) !void { | 1943 | fn invalidInstruction(mnemonic: Instruction.Mnemonic, ops: []const Instruction.Operand) !void { |
| 1943 | const err = Instruction.new(.none, mnemonic, ops); | 1944 | const err: Instruction = .new(.none, mnemonic, ops); |
| 1944 | try testing.expectError(error.InvalidInstruction, err); | 1945 | try testing.expectError(error.InvalidInstruction, err); |
| 1945 | } | 1946 | } |
| 1946 | 1947 | ||
| ... | @@ -1988,12 +1989,12 @@ test "invalid instruction" { | ... | @@ -1988,12 +1989,12 @@ test "invalid instruction" { |
| 1988 | .{ .reg = .r12d }, | 1989 | .{ .reg = .r12d }, |
| 1989 | }); | 1990 | }); |
| 1990 | try invalidInstruction(.push, &.{ | 1991 | try invalidInstruction(.push, &.{ |
| 1991 | .{ .imm = Instruction.Immediate.u(0x1000000000000000) }, | 1992 | .{ .imm = .u(0x1000000000000000) }, |
| 1992 | }); | 1993 | }); |
| 1993 | } | 1994 | } |
| 1994 | 1995 | ||
| 1995 | fn cannotEncode(mnemonic: Instruction.Mnemonic, ops: []const Instruction.Operand) !void { | 1996 | fn cannotEncode(mnemonic: Instruction.Mnemonic, ops: []const Instruction.Operand) !void { |
| 1996 | try testing.expectError(error.CannotEncode, Instruction.new(.none, mnemonic, ops)); | 1997 | try testing.expectError(error.CannotEncode, .new(.none, mnemonic, ops)); |
| 1997 | } | 1998 | } |
| 1998 | 1999 | ||
| 1999 | test "cannot encode" { | 2000 | test "cannot encode" { |
| ... | @@ -2177,7 +2178,7 @@ const Assembler = struct { | ... | @@ -2177,7 +2178,7 @@ const Assembler = struct { |
| 2177 | 2178 | ||
| 2178 | pub fn assemble(as: *Assembler, writer: anytype) !void { | 2179 | pub fn assemble(as: *Assembler, writer: anytype) !void { |
| 2179 | while (try as.next()) |parsed_inst| { | 2180 | while (try as.next()) |parsed_inst| { |
| 2180 | const inst = try Instruction.new(.none, parsed_inst.mnemonic, &parsed_inst.ops); | 2181 | const inst: Instruction = try .new(.none, parsed_inst.mnemonic, &parsed_inst.ops); |
| 2181 | try inst.encode(writer, .{}); | 2182 | try inst.encode(writer, .{}); |
| 2182 | } | 2183 | } |
| 2183 | } | 2184 | } |
src/link/MachO.zig+1-1| ... | @@ -3548,7 +3548,7 @@ pub fn getTarget(self: MachO) std.Target { | ... | @@ -3548,7 +3548,7 @@ pub fn getTarget(self: MachO) std.Target { |
| 3548 | pub fn invalidateKernelCache(dir: fs.Dir, sub_path: []const u8) !void { | 3548 | pub fn invalidateKernelCache(dir: fs.Dir, sub_path: []const u8) !void { |
| 3549 | const tracy = trace(@src()); | 3549 | const tracy = trace(@src()); |
| 3550 | defer tracy.end(); | 3550 | defer tracy.end(); |
| 3551 | if (comptime builtin.target.isDarwin() and builtin.target.cpu.arch == .aarch64) { | 3551 | if (builtin.target.isDarwin() and builtin.target.cpu.arch == .aarch64) { |
| 3552 | try dir.copyFile(sub_path, dir, sub_path, .{}); | 3552 | try dir.copyFile(sub_path, dir, sub_path, .{}); |
| 3553 | } | 3553 | } |
| 3554 | } | 3554 | } |
test/behavior/align.zig+10-10| ... | @@ -277,8 +277,8 @@ test "function alignment" { | ... | @@ -277,8 +277,8 @@ test "function alignment" { |
| 277 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 277 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 278 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 278 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 279 | 279 | ||
| 280 | // function alignment is a compile error on wasm32/wasm64 | 280 | // function alignment is a compile error on wasm |
| 281 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | 281 | if (native_arch.isWasm()) return error.SkipZigTest; |
| 282 | 282 | ||
| 283 | const S = struct { | 283 | const S = struct { |
| 284 | fn alignExpr() align(@sizeOf(usize) * 2) i32 { | 284 | fn alignExpr() align(@sizeOf(usize) * 2) i32 { |
| ... | @@ -307,8 +307,8 @@ test "implicitly decreasing fn alignment" { | ... | @@ -307,8 +307,8 @@ test "implicitly decreasing fn alignment" { |
| 307 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 307 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 308 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 308 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 309 | 309 | ||
| 310 | // function alignment is a compile error on wasm32/wasm64 | 310 | // function alignment is a compile error on wasm |
| 311 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | 311 | if (native_arch.isWasm()) return error.SkipZigTest; |
| 312 | 312 | ||
| 313 | try testImplicitlyDecreaseFnAlign(alignedSmall, 1234); | 313 | try testImplicitlyDecreaseFnAlign(alignedSmall, 1234); |
| 314 | try testImplicitlyDecreaseFnAlign(alignedBig, 5678); | 314 | try testImplicitlyDecreaseFnAlign(alignedBig, 5678); |
| ... | @@ -331,9 +331,9 @@ test "@alignCast functions" { | ... | @@ -331,9 +331,9 @@ test "@alignCast functions" { |
| 331 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 331 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 332 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 332 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 333 | 333 | ||
| 334 | // function alignment is a compile error on wasm32/wasm64 | 334 | // function alignment is a compile error on wasm |
| 335 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | 335 | if (native_arch.isWasm()) return error.SkipZigTest; |
| 336 | if (native_arch == .thumb or native_arch == .thumbeb) return error.SkipZigTest; | 336 | if (native_arch.isThumb()) return error.SkipZigTest; |
| 337 | 337 | ||
| 338 | try expect(fnExpectsOnly1(simple4) == 0x19); | 338 | try expect(fnExpectsOnly1(simple4) == 0x19); |
| 339 | } | 339 | } |
| ... | @@ -496,9 +496,9 @@ test "align(N) on functions" { | ... | @@ -496,9 +496,9 @@ test "align(N) on functions" { |
| 496 | return error.SkipZigTest; | 496 | return error.SkipZigTest; |
| 497 | } | 497 | } |
| 498 | 498 | ||
| 499 | // function alignment is a compile error on wasm32/wasm64 | 499 | // function alignment is a compile error on wasm |
| 500 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | 500 | if (native_arch.isWasm()) return error.SkipZigTest; |
| 501 | if (native_arch == .thumb or native_arch == .thumbeb) return error.SkipZigTest; | 501 | if (native_arch.isThumb()) return error.SkipZigTest; |
| 502 | 502 | ||
| 503 | try expect((@intFromPtr(&overaligned_fn) & (0x1000 - 1)) == 0); | 503 | try expect((@intFromPtr(&overaligned_fn) & (0x1000 - 1)) == 0); |
| 504 | } | 504 | } |
test/behavior/asm.zig+1-1| ... | @@ -178,7 +178,7 @@ test "rw constraint (x86_64)" { | ... | @@ -178,7 +178,7 @@ test "rw constraint (x86_64)" { |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | test "asm modifiers (AArch64)" { | 180 | test "asm modifiers (AArch64)" { |
| 181 | if (builtin.target.cpu.arch != .aarch64) return error.SkipZigTest; | 181 | if (!builtin.target.cpu.arch.isAARCH64()) return error.SkipZigTest; |
| 182 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 182 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 183 | 183 | ||
| 184 | if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly | 184 | if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly |
test/behavior/call.zig+1| ... | @@ -660,6 +660,7 @@ test "arguments pointed to on stack into tailcall" { | ... | @@ -660,6 +660,7 @@ test "arguments pointed to on stack into tailcall" { |
| 660 | 660 | ||
| 661 | switch (builtin.cpu.arch) { | 661 | switch (builtin.cpu.arch) { |
| 662 | .wasm32, | 662 | .wasm32, |
| 663 | .wasm64, | ||
| 663 | .mips, | 664 | .mips, |
| 664 | .mipsel, | 665 | .mipsel, |
| 665 | .mips64, | 666 | .mips64, |
test/behavior/cast.zig+2-2| ... | @@ -124,7 +124,7 @@ test "@floatFromInt(f80)" { | ... | @@ -124,7 +124,7 @@ test "@floatFromInt(f80)" { |
| 124 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 124 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 125 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 125 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 126 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 126 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 127 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 127 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 128 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 128 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 129 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 129 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 130 | 130 | ||
| ... | @@ -1362,7 +1362,7 @@ test "cast f16 to wider types" { | ... | @@ -1362,7 +1362,7 @@ test "cast f16 to wider types" { |
| 1362 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1362 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1363 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1363 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1364 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1364 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1365 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 1365 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 1366 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 1366 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 1367 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1367 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1368 | 1368 |
test/behavior/eval.zig+1-1| ... | @@ -522,7 +522,7 @@ test "runtime 128 bit integer division" { | ... | @@ -522,7 +522,7 @@ test "runtime 128 bit integer division" { |
| 522 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 522 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 523 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 523 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 524 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 524 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 525 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 525 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 526 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 526 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 527 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 527 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 528 | 528 |
test/behavior/math.zig+4-4| ... | @@ -785,7 +785,7 @@ test "128-bit multiplication" { | ... | @@ -785,7 +785,7 @@ test "128-bit multiplication" { |
| 785 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 785 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 786 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 786 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 787 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 787 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 788 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 788 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 789 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 789 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 790 | 790 | ||
| 791 | { | 791 | { |
| ... | @@ -1374,7 +1374,7 @@ test "remainder division" { | ... | @@ -1374,7 +1374,7 @@ test "remainder division" { |
| 1374 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1374 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1375 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1375 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1376 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 1376 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 1377 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 1377 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 1378 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1378 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1379 | 1379 | ||
| 1380 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | 1380 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { |
| ... | @@ -1527,7 +1527,7 @@ test "@round f80" { | ... | @@ -1527,7 +1527,7 @@ test "@round f80" { |
| 1527 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1527 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1528 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1528 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1529 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1529 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1530 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 1530 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 1531 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 1531 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 1532 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1532 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1533 | 1533 | ||
| ... | @@ -1540,7 +1540,7 @@ test "@round f128" { | ... | @@ -1540,7 +1540,7 @@ test "@round f128" { |
| 1540 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1540 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1541 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1541 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1542 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1542 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1543 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 1543 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 1544 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 1544 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 1545 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1545 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1546 | 1546 |
test/behavior/maximum_minimum.zig+1-1| ... | @@ -122,7 +122,7 @@ test "@min/max for floats" { | ... | @@ -122,7 +122,7 @@ test "@min/max for floats" { |
| 122 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 122 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 123 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 123 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 124 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 124 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 125 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 125 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 126 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 126 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 127 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 127 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 128 | 128 |
test/behavior/muladd.zig+4-4| ... | @@ -58,7 +58,7 @@ test "@mulAdd f80" { | ... | @@ -58,7 +58,7 @@ test "@mulAdd f80" { |
| 58 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 58 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 59 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 59 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 60 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 60 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 61 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 61 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 62 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 62 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 63 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 63 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 64 | 64 | ||
| ... | @@ -79,7 +79,7 @@ test "@mulAdd f128" { | ... | @@ -79,7 +79,7 @@ test "@mulAdd f128" { |
| 79 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 79 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 80 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 80 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 81 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 81 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 82 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 82 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 83 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 83 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 84 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 84 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 85 | 85 | ||
| ... | @@ -189,7 +189,7 @@ test "vector f80" { | ... | @@ -189,7 +189,7 @@ test "vector f80" { |
| 189 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 189 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 190 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 190 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 191 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 191 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 192 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 192 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 193 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 193 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 194 | 194 | ||
| 195 | try comptime vector80(); | 195 | try comptime vector80(); |
| ... | @@ -216,7 +216,7 @@ test "vector f128" { | ... | @@ -216,7 +216,7 @@ test "vector f128" { |
| 216 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 216 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 217 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 217 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 218 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 218 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 219 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 219 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 220 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 220 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 221 | 221 | ||
| 222 | try comptime vector128(); | 222 | try comptime vector128(); |
test/behavior/saturating_arithmetic.zig+5-5| ... | @@ -164,10 +164,10 @@ test "saturating multiplication <= 32 bits" { | ... | @@ -164,10 +164,10 @@ test "saturating multiplication <= 32 bits" { |
| 164 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 164 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 165 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 165 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 166 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 166 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 167 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 167 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 168 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 168 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 169 | 169 | ||
| 170 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .wasm32) { | 170 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isWasm()) { |
| 171 | // https://github.com/ziglang/zig/issues/9660 | 171 | // https://github.com/ziglang/zig/issues/9660 |
| 172 | return error.SkipZigTest; | 172 | return error.SkipZigTest; |
| 173 | } | 173 | } |
| ... | @@ -264,10 +264,10 @@ test "saturating multiplication" { | ... | @@ -264,10 +264,10 @@ test "saturating multiplication" { |
| 264 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 264 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 265 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 265 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 266 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 266 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 267 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 267 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 268 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 268 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 269 | 269 | ||
| 270 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .wasm32) { | 270 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isWasm()) { |
| 271 | // https://github.com/ziglang/zig/issues/9660 | 271 | // https://github.com/ziglang/zig/issues/9660 |
| 272 | return error.SkipZigTest; | 272 | return error.SkipZigTest; |
| 273 | } | 273 | } |
| ... | @@ -311,7 +311,7 @@ test "saturating shift-left" { | ... | @@ -311,7 +311,7 @@ test "saturating shift-left" { |
| 311 | try testSatShl(i8, 127, 1, 127); | 311 | try testSatShl(i8, 127, 1, 127); |
| 312 | try testSatShl(i8, -128, 1, -128); | 312 | try testSatShl(i8, -128, 1, -128); |
| 313 | // TODO: remove this check once #9668 is completed | 313 | // TODO: remove this check once #9668 is completed |
| 314 | if (builtin.cpu.arch != .wasm32) { | 314 | if (!builtin.cpu.arch.isWasm()) { |
| 315 | // skip testing ints > 64 bits on wasm due to miscompilation / wasmtime ci error | 315 | // skip testing ints > 64 bits on wasm due to miscompilation / wasmtime ci error |
| 316 | try testSatShl(i128, maxInt(i128), 64, maxInt(i128)); | 316 | try testSatShl(i128, maxInt(i128), 64, maxInt(i128)); |
| 317 | try testSatShl(u128, maxInt(u128), 64, maxInt(u128)); | 317 | try testSatShl(u128, maxInt(u128), 64, maxInt(u128)); |
test/behavior/struct.zig+4-4| ... | @@ -418,8 +418,8 @@ test "packed struct 24bits" { | ... | @@ -418,8 +418,8 @@ test "packed struct 24bits" { |
| 418 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 418 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 419 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 419 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 420 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 420 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 421 | if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO | 421 | if (builtin.cpu.arch.isWasm()) return error.SkipZigTest; // TODO |
| 422 | if (comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; // TODO | 422 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; // TODO |
| 423 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 423 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 424 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 424 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 425 | 425 | ||
| ... | @@ -818,7 +818,7 @@ test "non-packed struct with u128 entry in union" { | ... | @@ -818,7 +818,7 @@ test "non-packed struct with u128 entry in union" { |
| 818 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 818 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 819 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 819 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 820 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 820 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 821 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 821 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 822 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 822 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 823 | 823 | ||
| 824 | const U = union(enum) { | 824 | const U = union(enum) { |
| ... | @@ -941,7 +941,7 @@ test "tuple assigned to variable" { | ... | @@ -941,7 +941,7 @@ test "tuple assigned to variable" { |
| 941 | 941 | ||
| 942 | test "comptime struct field" { | 942 | test "comptime struct field" { |
| 943 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 943 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 944 | if (comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; // TODO | 944 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; // TODO |
| 945 | 945 | ||
| 946 | const T = struct { | 946 | const T = struct { |
| 947 | a: i32, | 947 | a: i32, |
test/behavior/var_args.zig+5-5| ... | @@ -100,7 +100,7 @@ test "simple variadic function" { | ... | @@ -100,7 +100,7 @@ test "simple variadic function" { |
| 100 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 100 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 101 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 101 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 102 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 102 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 103 | if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) { | 103 | if (builtin.os.tag != .macos and builtin.cpu.arch.isAARCH64()) { |
| 104 | // https://github.com/ziglang/zig/issues/14096 | 104 | // https://github.com/ziglang/zig/issues/14096 |
| 105 | return error.SkipZigTest; | 105 | return error.SkipZigTest; |
| 106 | } | 106 | } |
| ... | @@ -161,7 +161,7 @@ test "coerce reference to var arg" { | ... | @@ -161,7 +161,7 @@ test "coerce reference to var arg" { |
| 161 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 161 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 162 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 162 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 163 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 163 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 164 | if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) { | 164 | if (builtin.os.tag != .macos and builtin.cpu.arch.isAARCH64()) { |
| 165 | // https://github.com/ziglang/zig/issues/14096 | 165 | // https://github.com/ziglang/zig/issues/14096 |
| 166 | return error.SkipZigTest; | 166 | return error.SkipZigTest; |
| 167 | } | 167 | } |
| ... | @@ -194,7 +194,7 @@ test "variadic functions" { | ... | @@ -194,7 +194,7 @@ test "variadic functions" { |
| 194 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 194 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 195 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 195 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 196 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 196 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 197 | if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) { | 197 | if (builtin.os.tag != .macos and builtin.cpu.arch.isAARCH64()) { |
| 198 | // https://github.com/ziglang/zig/issues/14096 | 198 | // https://github.com/ziglang/zig/issues/14096 |
| 199 | return error.SkipZigTest; | 199 | return error.SkipZigTest; |
| 200 | } | 200 | } |
| ... | @@ -239,7 +239,7 @@ test "copy VaList" { | ... | @@ -239,7 +239,7 @@ test "copy VaList" { |
| 239 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 239 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 240 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 240 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 241 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 241 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 242 | if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) { | 242 | if (builtin.os.tag != .macos and builtin.cpu.arch.isAARCH64()) { |
| 243 | // https://github.com/ziglang/zig/issues/14096 | 243 | // https://github.com/ziglang/zig/issues/14096 |
| 244 | return error.SkipZigTest; | 244 | return error.SkipZigTest; |
| 245 | } | 245 | } |
| ... | @@ -273,7 +273,7 @@ test "unused VaList arg" { | ... | @@ -273,7 +273,7 @@ test "unused VaList arg" { |
| 273 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 273 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 274 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 274 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 275 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 275 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 276 | if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) { | 276 | if (builtin.os.tag != .macos and builtin.cpu.arch.isAARCH64()) { |
| 277 | // https://github.com/ziglang/zig/issues/14096 | 277 | // https://github.com/ziglang/zig/issues/14096 |
| 278 | return error.SkipZigTest; | 278 | return error.SkipZigTest; |
| 279 | } | 279 | } |
test/behavior/vector.zig+4-4| ... | @@ -101,7 +101,7 @@ test "vector float operators" { | ... | @@ -101,7 +101,7 @@ test "vector float operators" { |
| 101 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 101 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 102 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 102 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 103 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 103 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 104 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 104 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 105 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 105 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 106 | 106 | ||
| 107 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) { | 107 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) { |
| ... | @@ -754,7 +754,7 @@ test "vector reduce operation" { | ... | @@ -754,7 +754,7 @@ test "vector reduce operation" { |
| 754 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 754 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 755 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 755 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 756 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 756 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 757 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; | 757 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 758 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 758 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 759 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21091 | 759 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21091 |
| 760 | 760 | ||
| ... | @@ -989,7 +989,7 @@ test "saturating multiplication" { | ... | @@ -989,7 +989,7 @@ test "saturating multiplication" { |
| 989 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 989 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 990 | 990 | ||
| 991 | // TODO: once #9660 has been solved, remove this line | 991 | // TODO: once #9660 has been solved, remove this line |
| 992 | if (builtin.target.cpu.arch == .wasm32) return error.SkipZigTest; | 992 | if (builtin.target.cpu.arch.isWasm()) return error.SkipZigTest; |
| 993 | 993 | ||
| 994 | const S = struct { | 994 | const S = struct { |
| 995 | fn doTheTest() !void { | 995 | fn doTheTest() !void { |
| ... | @@ -1256,7 +1256,7 @@ test "byte vector initialized in inline function" { | ... | @@ -1256,7 +1256,7 @@ test "byte vector initialized in inline function" { |
| 1256 | if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | 1256 | if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; |
| 1257 | 1257 | ||
| 1258 | if (comptime builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and | 1258 | if (comptime builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and |
| 1259 | builtin.cpu.features.isEnabled(@intFromEnum(std.Target.x86.Feature.avx512f))) | 1259 | std.Target.x86.featureSetHas(builtin.cpu.features, .avx512f)) |
| 1260 | { | 1260 | { |
| 1261 | // TODO https://github.com/ziglang/zig/issues/13279 | 1261 | // TODO https://github.com/ziglang/zig/issues/13279 |
| 1262 | return error.SkipZigTest; | 1262 | return error.SkipZigTest; |
test/behavior/wrapping_arithmetic.zig+1-1| ... | @@ -83,7 +83,7 @@ test "wrapping multiplication" { | ... | @@ -83,7 +83,7 @@ test "wrapping multiplication" { |
| 83 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 83 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 84 | 84 | ||
| 85 | // TODO: once #9660 has been solved, remove this line | 85 | // TODO: once #9660 has been solved, remove this line |
| 86 | if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; | 86 | if (builtin.cpu.arch.isWasm()) return error.SkipZigTest; |
| 87 | 87 | ||
| 88 | const S = struct { | 88 | const S = struct { |
| 89 | fn doTheTest() !void { | 89 | fn doTheTest() !void { |