diff --git a/build.zig b/build.zig index 07041d026..011f742d8 100644 --- a/build.zig +++ b/build.zig @@ -122,16 +122,19 @@ pub fn build(b: *Builder) !void { } const modes = chosen_modes[0..chosen_mode_index]; + const multi_and_single = [_]bool{ false, true }; + const just_multi = [_]bool{false}; + // run stage1 `zig fmt` on this build.zig file just to make sure it works test_step.dependOn(&fmt_build_zig.step); const fmt_step = b.step("test-fmt", "Run zig fmt against build.zig to make sure it works"); fmt_step.dependOn(&fmt_build_zig.step); - test_step.dependOn(tests.addPkgTests(b, test_filter, "test/stage1/behavior.zig", "behavior", "Run the behavior tests", modes, skip_non_native)); + test_step.dependOn(tests.addPkgTests(b, test_filter, "test/stage1/behavior.zig", "behavior", "Run the behavior tests", modes, multi_and_single, skip_non_native)); - test_step.dependOn(tests.addPkgTests(b, test_filter, "std/std.zig", "std", "Run the standard library tests", modes, skip_non_native)); + test_step.dependOn(tests.addPkgTests(b, test_filter, "std/std.zig", "std", "Run the standard library tests", modes, multi_and_single, skip_non_native)); - test_step.dependOn(tests.addPkgTests(b, test_filter, "std/special/compiler_rt.zig", "compiler-rt", "Run the compiler_rt tests", modes, skip_non_native)); + test_step.dependOn(tests.addPkgTests(b, test_filter, "std/special/compiler_rt.zig", "compiler-rt", "Run the compiler_rt tests", modes, just_multi, skip_non_native)); test_step.dependOn(tests.addCompareOutputTests(b, test_filter, modes)); test_step.dependOn(tests.addStandaloneTests(b, test_filter, modes)); diff --git a/src/analyze.cpp b/src/analyze.cpp index 4bb3de095..80e22c6c6 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3346,7 +3346,8 @@ static void resolve_use_decl(CodeGen *g, TldUsingNamespace *tld_using_namespace, static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, ScopeDecls *dest_decls_scope) { if (using_namespace->base.resolution == TldResolutionOk || - using_namespace->base.resolution == TldResolutionInvalid) + using_namespace->base.resolution == TldResolutionInvalid || + using_namespace->using_namespace_value != nullptr) { return; } diff --git a/std/build.zig b/std/build.zig index fc0786094..3a0c34c8d 100644 --- a/std/build.zig +++ b/std/build.zig @@ -41,9 +41,11 @@ pub const Builder = struct { env_map: *BufMap, top_level_steps: ArrayList(*TopLevelStep), install_prefix: ?[]const u8, - search_prefixes: ArrayList([]const u8), + dest_dir: ?[]const u8, lib_dir: ?[]const u8, exe_dir: ?[]const u8, + install_path: []const u8, + search_prefixes: ArrayList([]const u8), installed_files: ArrayList(InstalledFile), build_root: []const u8, cache_root: []const u8, @@ -125,10 +127,11 @@ pub const Builder = struct { .top_level_steps = ArrayList(*TopLevelStep).init(allocator), .default_step = undefined, .env_map = env_map, - .install_prefix = null, .search_prefixes = ArrayList([]const u8).init(allocator), + .install_prefix = null, .lib_dir = null, .exe_dir = null, + .dest_dir = env_map.get("DESTDIR"), .installed_files = ArrayList(InstalledFile).init(allocator), .install_tls = TopLevelStep{ .step = Step.initNoOp("install", allocator), @@ -142,6 +145,7 @@ pub const Builder = struct { .is_release = false, .override_std_dir = null, .override_lib_dir = null, + .install_path = undefined, }; try self.top_level_steps.append(&self.install_tls); try self.top_level_steps.append(&self.uninstall_tls); @@ -164,14 +168,19 @@ pub const Builder = struct { } fn resolveInstallPrefix(self: *Builder) void { - const prefix = if (self.install_prefix) |prefix| prefix else blk: { - const prefix = self.cache_root; - self.install_prefix = prefix; - break :blk prefix; - }; - - self.lib_dir = fs.path.join(self.allocator, [_][]const u8{ prefix, "lib" }) catch unreachable; - self.exe_dir = fs.path.join(self.allocator, [_][]const u8{ prefix, "bin" }) catch unreachable; + if (self.dest_dir) |dest_dir| { + const install_prefix = self.install_prefix orelse "/usr"; + self.install_path = fs.path.join(self.allocator, [_][]const u8{ dest_dir, install_prefix }) catch unreachable; + } else { + const install_prefix = self.install_prefix orelse blk: { + const p = self.cache_root; + self.install_prefix = p; + break :blk p; + }; + self.install_path = install_prefix; + } + self.lib_dir = fs.path.join(self.allocator, [_][]const u8{ self.install_path, "lib" }) catch unreachable; + self.exe_dir = fs.path.join(self.allocator, [_][]const u8{ self.install_path, "bin" }) catch unreachable; } pub fn addExecutable(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep { @@ -884,7 +893,7 @@ pub const Builder = struct { fn getInstallPath(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) []const u8 { const base_dir = switch (dir) { - .Prefix => self.install_prefix.?, + .Prefix => self.install_path, .Bin => self.exe_dir.?, .Lib => self.lib_dir.?, }; diff --git a/std/debug.zig b/std/debug.zig index c41694486..7d1fd6ce4 100644 --- a/std/debug.zig +++ b/std/debug.zig @@ -2353,7 +2353,7 @@ pub fn attachSegfaultHandler() void { fn resetSegfaultHandler() void { if (windows.is_the_target) { if (windows_segfault_handle) |handle| { - assert(windows.kernel32.RemoveVectoredExceptionHandler() != 0); + assert(windows.kernel32.RemoveVectoredExceptionHandler(handle) != 0); windows_segfault_handle = null; } return; diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig index 5064e9db2..a5bbefa1d 100644 --- a/std/special/compiler_rt.zig +++ b/std/special/compiler_rt.zig @@ -127,6 +127,7 @@ comptime { @export("__udivmoddi4", @import("compiler_rt/udivmoddi4.zig").__udivmoddi4, linkage); @export("__popcountdi2", @import("compiler_rt/popcountdi2.zig").__popcountdi2, linkage); + @export("__muldi3", @import("compiler_rt/muldi3.zig").__muldi3, linkage); @export("__divmoddi4", __divmoddi4, linkage); @export("__divsi3", __divsi3, linkage); @export("__divdi3", __divdi3, linkage); @@ -147,6 +148,8 @@ comptime { @export("__aeabi_unwind_cpp_pr1", __aeabi_unwind_cpp_pr1, linkage); @export("__aeabi_unwind_cpp_pr2", __aeabi_unwind_cpp_pr2, linkage); + @export("__aeabi_lmul", @import("compiler_rt/muldi3.zig").__muldi3, linkage); + @export("__aeabi_ldivmod", __aeabi_ldivmod, linkage); @export("__aeabi_uldivmod", __aeabi_uldivmod, linkage); diff --git a/std/special/compiler_rt/divti3.zig b/std/special/compiler_rt/divti3.zig index d5b2778a3..477ce2cb9 100644 --- a/std/special/compiler_rt/divti3.zig +++ b/std/special/compiler_rt/divti3.zig @@ -1,6 +1,5 @@ const udivmod = @import("udivmod.zig").udivmod; const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); pub extern fn __divti3(a: i128, b: i128) i128 { @setRuntimeSafety(builtin.is_test); diff --git a/std/special/compiler_rt/muldi3.zig b/std/special/compiler_rt/muldi3.zig new file mode 100644 index 000000000..7a955120f --- /dev/null +++ b/std/special/compiler_rt/muldi3.zig @@ -0,0 +1,54 @@ +const builtin = @import("builtin"); + +// Ported from +// https://github.com/llvm/llvm-project/blob/552c2c09d354a3ad9c1c9647e0a3bb5099c31088/compiler-rt/lib/builtins/muldi3.c + +const dwords = extern union { + all: i64, + s: switch (builtin.endian) { + .Little => extern struct { + low: u32, + high: u32, + }, + .Big => extern struct { + high: u32, + low: u32, + }, + }, +}; + +fn __muldsi3(a: u32, b: u32) i64 { + @setRuntimeSafety(builtin.is_test); + + const bits_in_word_2 = @sizeOf(i32) * 8 / 2; + const lower_mask = (~u32(0)) >> bits_in_word_2; + + var r: dwords = undefined; + r.s.low = (a & lower_mask) *% (b & lower_mask); + var t: u32 = r.s.low >> bits_in_word_2; + r.s.low &= lower_mask; + t += (a >> bits_in_word_2) *% (b & lower_mask); + r.s.low +%= (t & lower_mask) << bits_in_word_2; + r.s.high = t >> bits_in_word_2; + t = r.s.low >> bits_in_word_2; + r.s.low &= lower_mask; + t +%= (b >> bits_in_word_2) *% (a & lower_mask); + r.s.low +%= (t & lower_mask) << bits_in_word_2; + r.s.high +%= t >> bits_in_word_2; + r.s.high +%= (a >> bits_in_word_2) *% (b >> bits_in_word_2); + return r.all; +} + +pub extern fn __muldi3(a: i64, b: i64) i64 { + @setRuntimeSafety(builtin.is_test); + + const x = dwords{ .all = a }; + const y = dwords{ .all = b }; + var r = dwords{ .all = __muldsi3(x.s.low, y.s.low) }; + r.s.high +%= x.s.high *% y.s.low +% x.s.low *% y.s.high; + return r.all; +} + +test "import muldi3" { + _ = @import("muldi3_test.zig"); +} diff --git a/std/special/compiler_rt/muldi3_test.zig b/std/special/compiler_rt/muldi3_test.zig new file mode 100644 index 000000000..db4daf1e1 --- /dev/null +++ b/std/special/compiler_rt/muldi3_test.zig @@ -0,0 +1,51 @@ +const __muldi3 = @import("muldi3.zig").__muldi3; +const testing = @import("std").testing; + +fn test__muldi3(a: i64, b: i64, expected: i64) void { + const x = __muldi3(a, b); + testing.expect(x == expected); +} + +test "muldi3" { + test__muldi3(0, 0, 0); + test__muldi3(0, 1, 0); + test__muldi3(1, 0, 0); + test__muldi3(0, 10, 0); + test__muldi3(10, 0, 0); + test__muldi3(0, 81985529216486895, 0); + test__muldi3(81985529216486895, 0, 0); + + test__muldi3(0, -1, 0); + test__muldi3(-1, 0, 0); + test__muldi3(0, -10, 0); + test__muldi3(-10, 0, 0); + test__muldi3(0, -81985529216486895, 0); + test__muldi3(-81985529216486895, 0, 0); + + test__muldi3(1, 1, 1); + test__muldi3(1, 10, 10); + test__muldi3(10, 1, 10); + test__muldi3(1, 81985529216486895, 81985529216486895); + test__muldi3(81985529216486895, 1, 81985529216486895); + + test__muldi3(1, -1, -1); + test__muldi3(1, -10, -10); + test__muldi3(-10, 1, -10); + test__muldi3(1, -81985529216486895, -81985529216486895); + test__muldi3(-81985529216486895, 1, -81985529216486895); + + test__muldi3(3037000499, 3037000499, 9223372030926249001); + test__muldi3(-3037000499, 3037000499, -9223372030926249001); + test__muldi3(3037000499, -3037000499, -9223372030926249001); + test__muldi3(-3037000499, -3037000499, 9223372030926249001); + + test__muldi3(4398046511103, 2097152, 9223372036852678656); + test__muldi3(-4398046511103, 2097152, -9223372036852678656); + test__muldi3(4398046511103, -2097152, -9223372036852678656); + test__muldi3(-4398046511103, -2097152, 9223372036852678656); + + test__muldi3(2097152, 4398046511103, 9223372036852678656); + test__muldi3(-2097152, 4398046511103, -9223372036852678656); + test__muldi3(2097152, -4398046511103, -9223372036852678656); + test__muldi3(-2097152, -4398046511103, 9223372036852678656); +} diff --git a/test/tests.zig b/test/tests.zig index d94c012ac..c8aea3359 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -170,6 +170,7 @@ pub fn addPkgTests( name: []const u8, desc: []const u8, modes: []const Mode, + single_threaded_list: []const bool, skip_non_native: bool, ) *build.Step { const step = b.step(b.fmt("test-{}", name), desc); @@ -179,7 +180,7 @@ pub fn addPkgTests( continue; for (modes) |mode| { for ([_]bool{ false, true }) |link_libc| { - for ([_]bool{ false, true }) |single_threaded| { + for (single_threaded_list) |single_threaded| { if (link_libc and !is_native) { // don't assume we have a cross-compiling libc set up continue;