authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-02-04 14:17:47-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-02-04 14:17:47-07:00
log09cee1d5e34dd4187242a693c2d7b5a9d1e689b1
tree70be147cdf59171bda9079abb3c5fe318ffad72b
parentfab9b7110ed1fa7bb082aad5e095047441db2b24
parentb7c96c3bbdc0e2172cf9edb0c9c7c52f86c2311e

Merge remote-tracking branch 'origin/master' into llvm16


17 files changed, 956 insertions(+), 212 deletions(-)

lib/c.zig+1-1
......@@ -354,7 +354,7 @@ fn clone() callconv(.Naked) void {
354354 \\ ecall
355355 );
356356 },
357 .mips, .mipsel => {
357 .mips, .mipsel, .mips64, .mips64el => {
358358 // __clone(func, stack, flags, arg, ptid, tls, ctid)
359359 // 3, 4, 5, 6, 7, 8, 9
360360
lib/compiler_rt/README.md+20-20
......@@ -51,31 +51,31 @@ Integer and Float Operations
5151| Done | Name | a | b | Out | Comment |
5252| ------ | ------------- | ---- | ---- | ---- | ------------------------------ |
5353| | | | | | **Integer Bit Operations** |
54| ✓ | __clzsi2 | u32 | ∅ | i32 | count leading zeroes |
55| ✓ | __clzdi2 | u64 | ∅ | i32 | count leading zeroes |
56| ✓ | __clzti2 | u128 | ∅ | i32 | count trailing zeros |
54| ✓ | __clzsi2 | u32 | ∅ | i32 | count leading zeros |
55| ✓ | __clzdi2 | u64 | ∅ | i32 | count leading zeros |
56| ✓ | __clzti2 | u128 | ∅ | i32 | count leading zeros |
5757| ✓ | __ctzsi2 | u32 | ∅ | i32 | count trailing zeros |
5858| ✓ | __ctzdi2 | u64 | ∅ | i32 | count trailing zeros |
59| ✓ | __ctzti2 | u128 | ∅ | i32 | count leading zeroes |
60| ✓ | __ffssi2 | u32 | ∅ | i32 | count leading zeroes |
61| ✓ | __ffsdi2 | u64 | ∅ | i32 | count leading zeroes |
62| ✓ | __ffsti2 | u128 | ∅ | i32 | count leading zeroes |
63| ✓ | __paritysi2 | u32 | ∅ | i32 | find least significant 1 bit |
64| ✓ | __paritydi2 | u64 | ∅ | i32 | find least significant 1 bit |
65| ✓ | __parityti2 | u128 | ∅ | i32 | find least significant 1 bit |
59| ✓ | __ctzti2 | u128 | ∅ | i32 | count trailing zeros |
60| ✓ | __ffssi2 | u32 | ∅ | i32 | find least significant 1 bit |
61| ✓ | __ffsdi2 | u64 | ∅ | i32 | find least significant 1 bit |
62| ✓ | __ffsti2 | u128 | ∅ | i32 | find least significant 1 bit |
63| ✓ | __paritysi2 | u32 | ∅ | i32 | bit parity |
64| ✓ | __paritydi2 | u64 | ∅ | i32 | bit parity |
65| ✓ | __parityti2 | u128 | ∅ | i32 | bit parity |
6666| ✓ | __popcountsi2 | u32 | ∅ | i32 | bit population |
6767| ✓ | __popcountdi2 | u64 | ∅ | i32 | bit population |
6868| ✓ | __popcountti2 | u128 | ∅ | i32 | bit population |
69| ✓ | __bswapsi2 | u32 | ∅ | i32 | bit parity |
70| ✓ | __bswapdi2 | u64 | ∅ | i32 | bit parity |
71| ✓ | __bswapti2 | u128 | ∅ | i32 | bit parity |
69| ✓ | __bswapsi2 | u32 | ∅ | i32 | byte swap |
70| ✓ | __bswapdi2 | u64 | ∅ | i32 | byte swap |
71| ✓ | __bswapti2 | u128 | ∅ | i32 | byte swap |
7272| | | | | | **Integer Comparison** |
7373| ✓ | __cmpsi2 | i32 | i32 | i32 | `(a<b) -> 0, (a==b) -> 1, (a>b) -> 2` |
7474| ✓ | __cmpdi2 | i64 | i64 | i32 | .. |
7575| ✓ | __cmpti2 | i128 | i128 | i32 | .. |
76| ✓ | __ucmpsi2 | i32 | i32 | i32 | `(a<b) -> 0, (a==b) -> 1, (a>b) -> 2` |
77| ✓ | __ucmpdi2 | i64 | i64 | i32 | .. |
78| ✓ | __ucmpti2 | i128 | i128 | i32 | .. |
76| ✓ | __ucmpsi2 | u32 | u32 | i32 | `(a<b) -> 0, (a==b) -> 1, (a>b) -> 2` |
77| ✓ | __ucmpdi2 | u64 | u64 | i32 | .. |
78| ✓ | __ucmpti2 | u128 | u128 | i32 | .. |
7979| | | | | | **Integer Arithmetic** |
8080| ✗ | __ashlsi3 | i32 | i32 | i32 | `a << b` [^unused_rl78] |
8181| ✓ | __ashldi3 | i64 | i32 | i64 | .. |
......@@ -165,7 +165,7 @@ Integer and Float Operations
165165| ✓ | _Qp_qtos |*f128 | ∅ | f32 | .. SPARC |
166166| ✓ | __trunckfdf2 | f128 | ∅ | f64 | .. PPC |
167167| ✓ | _Qp_qtod |*f128 | ∅ | f64 | .. SPARC |
168| ✓ | __fixhfsi | f16 | ∅ | i32 | rounding towards zero |
168| ✓ | __fixhfsi | f16 | ∅ | i32 | float to int, rounding towards zero |
169169| ✓ | __fixsfsi | f32 | ∅ | i32 | .. |
170170| ✓ | __fixdfsi | f64 | ∅ | i32 | .. |
171171| ✓ | __fixtfsi | f128 | ∅ | i32 | .. |
......@@ -180,7 +180,7 @@ Integer and Float Operations
180180| ✓ | __fixdfti | f64 | ∅ | i128 | .. |
181181| ✓ | __fixtfti | f128 | ∅ | i128 | .. |
182182| ✓ | __fixxfti | f80 | ∅ | i128 | .. |
183| ✓ | __fixunshfsi | f16 | ∅ | u32 | rounding towards zero. negative values become 0. |
183| ✓ | __fixunshfsi | f16 | ∅ | u32 | float to uint, rounding towards zero. negative values become 0. |
184184| ✓ | __fixunssfsi | f32 | ∅ | u32 | .. |
185185| ✓ | __fixunsdfsi | f64 | ∅ | u32 | .. |
186186| ✓ | __fixunstfsi | f128 | ∅ | u32 | .. |
......@@ -195,7 +195,7 @@ Integer and Float Operations
195195| ✓ | __fixunsdfti | f64 | ∅ | u128 | .. |
196196| ✓ | __fixunstfti | f128 | ∅ | u128 | .. |
197197| ✓ | __fixunsxfti | f80 | ∅ | u128 | .. |
198| ✓ | __floatsihf | i32 | ∅ | f16 | int_to_float conversions |
198| ✓ | __floatsihf | i32 | ∅ | f16 | int to float |
199199| ✓ | __floatsisf | i32 | ∅ | f32 | .. |
200200| ✓ | __floatsidf | i32 | ∅ | f64 | .. |
201201| ✓ | __floatsitf | i32 | ∅ | f128 | .. |
......@@ -209,7 +209,7 @@ Integer and Float Operations
209209| ✓ | __floattidf | i128 | ∅ | f64 | .. |
210210| ✓ | __floattitf | i128 | ∅ | f128 | .. |
211211| ✓ | __floattixf | i128 | ∅ | f80 | .. |
212| ✓ | __floatunsihf | u32 | ∅ | f16 | uint_to_float conversions |
212| ✓ | __floatunsihf | u32 | ∅ | f16 | uint to float |
213213| ✓ | __floatunsisf | u32 | ∅ | f32 | .. |
214214| ✓ | __floatunsidf | u32 | ∅ | f64 | .. |
215215| ✓ | __floatunsitf | u32 | ∅ | f128 | .. |
lib/std/Build.zig+60-70
......@@ -109,6 +109,8 @@ host: NativeTargetInfo,
109109
110110dep_prefix: []const u8 = "",
111111
112modules: std.StringArrayHashMap(*Module),
113
112114pub const ExecError = error{
113115 ReadFailure,
114116 ExitCodeFailure,
......@@ -232,6 +234,7 @@ pub fn create(
232234 .install_path = undefined,
233235 .args = null,
234236 .host = host,
237 .modules = std.StringArrayHashMap(*Module).init(allocator),
235238 };
236239 try self.top_level_steps.append(&self.install_tls);
237240 try self.top_level_steps.append(&self.uninstall_tls);
......@@ -305,6 +308,7 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: []const u8)
305308 .glibc_runtimes_dir = parent.glibc_runtimes_dir,
306309 .host = parent.host,
307310 .dep_prefix = parent.fmt("{s}{s}.", .{ parent.dep_prefix, dep_name }),
311 .modules = std.StringArrayHashMap(*Module).init(allocator),
308312 };
309313 try child.top_level_steps.append(&child.install_tls);
310314 try child.top_level_steps.append(&child.uninstall_tls);
......@@ -539,6 +543,49 @@ pub fn addAssembly(b: *Build, options: AssemblyOptions) *CompileStep {
539543 return obj_step;
540544}
541545
546pub const AddModuleOptions = struct {
547 name: []const u8,
548 source_file: FileSource,
549 dependencies: []const ModuleDependency = &.{},
550};
551
552pub fn addModule(b: *Build, options: AddModuleOptions) void {
553 b.modules.put(b.dupe(options.name), b.createModule(.{
554 .source_file = options.source_file,
555 .dependencies = options.dependencies,
556 })) catch @panic("OOM");
557}
558
559pub const ModuleDependency = struct {
560 name: []const u8,
561 module: *Module,
562};
563
564pub const CreateModuleOptions = struct {
565 source_file: FileSource,
566 dependencies: []const ModuleDependency = &.{},
567};
568
569/// Prefer to use `addModule` which will make the module available to other
570/// packages which depend on this package.
571pub fn createModule(b: *Build, options: CreateModuleOptions) *Module {
572 const module = b.allocator.create(Module) catch @panic("OOM");
573 module.* = .{
574 .builder = b,
575 .source_file = options.source_file,
576 .dependencies = moduleDependenciesToArrayHashMap(b.allocator, options.dependencies),
577 };
578 return module;
579}
580
581fn moduleDependenciesToArrayHashMap(arena: Allocator, deps: []const ModuleDependency) std.StringArrayHashMap(*Module) {
582 var result = std.StringArrayHashMap(*Module).init(arena);
583 for (deps) |dep| {
584 result.put(dep.name, dep.module) catch @panic("OOM");
585 }
586 return result;
587}
588
542589/// Initializes a RunStep with argv, which must at least have the path to the
543590/// executable. More command line arguments can be added with `addArg`,
544591/// `addArgs`, and `addArtifactArg`.
......@@ -588,24 +635,6 @@ pub fn dupePath(self: *Build, bytes: []const u8) []u8 {
588635 return the_copy;
589636}
590637
591/// Duplicates a package recursively.
592pub fn dupePkg(self: *Build, package: Pkg) Pkg {
593 var the_copy = Pkg{
594 .name = self.dupe(package.name),
595 .source = package.source.dupe(self),
596 };
597
598 if (package.dependencies) |dependencies| {
599 const new_dependencies = self.allocator.alloc(Pkg, dependencies.len) catch @panic("OOM");
600 the_copy.dependencies = new_dependencies;
601
602 for (dependencies) |dep_package, i| {
603 new_dependencies[i] = self.dupePkg(dep_package);
604 }
605 }
606 return the_copy;
607}
608
609638pub fn addWriteFile(self: *Build, file_path: []const u8, data: []const u8) *WriteFileStep {
610639 const write_file_step = self.addWriteFiles();
611640 write_file_step.add(file_path, data);
......@@ -1479,6 +1508,12 @@ pub const Dependency = struct {
14791508 panic("unable to find artifact '{s}'", .{name});
14801509 };
14811510 }
1511
1512 pub fn module(d: *Dependency, name: []const u8) *Module {
1513 return d.builder.modules.get(name) orelse {
1514 panic("unable to find module '{s}'", .{name});
1515 };
1516 }
14821517};
14831518
14841519pub fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency {
......@@ -1548,10 +1583,13 @@ test "builder.findProgram compiles" {
15481583 _ = builder.findProgram(&[_][]const u8{}, &[_][]const u8{}) catch null;
15491584}
15501585
1551pub const Pkg = struct {
1552 name: []const u8,
1553 source: FileSource,
1554 dependencies: ?[]const Pkg = null,
1586pub const Module = struct {
1587 builder: *Build,
1588 /// This could either be a generated file, in which case the module
1589 /// contains exactly one file, or it could be a path to the root source
1590 /// file of directory of files which constitute the module.
1591 source_file: FileSource,
1592 dependencies: std.StringArrayHashMap(*Module),
15551593};
15561594
15571595/// A file that is generated by a build step.
......@@ -1713,54 +1751,6 @@ pub fn serializeCpu(allocator: Allocator, cpu: std.Target.Cpu) ![]const u8 {
17131751 }
17141752}
17151753
1716test "dupePkg()" {
1717 if (builtin.os.tag == .wasi) return error.SkipZigTest;
1718
1719 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
1720 defer arena.deinit();
1721
1722 const host = try NativeTargetInfo.detect(.{});
1723
1724 var builder = try Build.create(
1725 arena.allocator(),
1726 "test",
1727 "test",
1728 "test",
1729 "test",
1730 host,
1731 );
1732 defer builder.destroy();
1733
1734 var pkg_dep = Pkg{
1735 .name = "pkg_dep",
1736 .source = .{ .path = "/not/a/pkg_dep.zig" },
1737 };
1738 var pkg_top = Pkg{
1739 .name = "pkg_top",
1740 .source = .{ .path = "/not/a/pkg_top.zig" },
1741 .dependencies = &[_]Pkg{pkg_dep},
1742 };
1743 const duped = builder.dupePkg(pkg_top);
1744
1745 const original_deps = pkg_top.dependencies.?;
1746 const dupe_deps = duped.dependencies.?;
1747
1748 // probably the same top level package details
1749 try std.testing.expectEqualStrings(pkg_top.name, duped.name);
1750
1751 // probably the same dependencies
1752 try std.testing.expectEqual(original_deps.len, dupe_deps.len);
1753 try std.testing.expectEqual(original_deps[0].name, pkg_dep.name);
1754
1755 // could segfault otherwise if pointers in duplicated package's fields are
1756 // the same as those in stack allocated package's fields
1757 try std.testing.expect(dupe_deps.ptr != original_deps.ptr);
1758 try std.testing.expect(duped.name.ptr != pkg_top.name.ptr);
1759 try std.testing.expect(duped.source.path.ptr != pkg_top.source.path.ptr);
1760 try std.testing.expect(dupe_deps[0].name.ptr != pkg_dep.name.ptr);
1761 try std.testing.expect(dupe_deps[0].source.path.ptr != pkg_dep.source.path.ptr);
1762}
1763
17641754test {
17651755 _ = CheckFileStep;
17661756 _ = CheckObjectStep;
lib/std/Build/CompileStep.zig+40-71
......@@ -16,7 +16,7 @@ const FileSource = std.Build.FileSource;
1616const PkgConfigPkg = std.Build.PkgConfigPkg;
1717const PkgConfigError = std.Build.PkgConfigError;
1818const ExecError = std.Build.ExecError;
19const Pkg = std.Build.Pkg;
19const Module = std.Build.Module;
2020const VcpkgRoot = std.Build.VcpkgRoot;
2121const InstallDir = std.Build.InstallDir;
2222const InstallArtifactStep = std.Build.InstallArtifactStep;
......@@ -99,7 +99,7 @@ root_src: ?FileSource,
9999out_h_filename: []const u8,
100100out_lib_filename: []const u8,
101101out_pdb_filename: []const u8,
102packages: ArrayList(Pkg),
102modules: std.StringArrayHashMap(*Module),
103103
104104object_src: []const u8,
105105
......@@ -334,7 +334,7 @@ pub fn create(builder: *std.Build, options: Options) *CompileStep {
334334 .out_pdb_filename = builder.fmt("{s}.pdb", .{name}),
335335 .major_only_filename = null,
336336 .name_only_filename = null,
337 .packages = ArrayList(Pkg).init(builder.allocator),
337 .modules = std.StringArrayHashMap(*Module).init(builder.allocator),
338338 .include_dirs = ArrayList(IncludeDir).init(builder.allocator),
339339 .link_objects = ArrayList(LinkObject).init(builder.allocator),
340340 .c_macros = ArrayList([]const u8).init(builder.allocator),
......@@ -946,29 +946,29 @@ pub fn addFrameworkPath(self: *CompileStep, dir_path: []const u8) void {
946946 self.framework_dirs.append(self.builder.dupe(dir_path)) catch @panic("OOM");
947947}
948948
949pub fn addPackage(self: *CompileStep, package: Pkg) void {
950 self.packages.append(self.builder.dupePkg(package)) catch @panic("OOM");
951 self.addRecursiveBuildDeps(package);
949/// Adds a module to be used with `@import` and exposing it in the current
950/// package's module table using `name`.
951pub fn addModule(cs: *CompileStep, name: []const u8, module: *Module) void {
952 cs.modules.put(cs.builder.dupe(name), module) catch @panic("OOM");
953 cs.addRecursiveBuildDeps(module);
952954}
953955
954pub fn addOptions(self: *CompileStep, package_name: []const u8, options: *OptionsStep) void {
955 self.addPackage(options.getPackage(package_name));
956/// Adds a module to be used with `@import` without exposing it in the current
957/// package's module table.
958pub fn addAnonymousModule(cs: *CompileStep, name: []const u8, options: std.Build.CreateModuleOptions) void {
959 const module = cs.builder.createModule(options);
960 return addModule(cs, name, module);
956961}
957962
958fn addRecursiveBuildDeps(self: *CompileStep, package: Pkg) void {
959 package.source.addStepDependencies(&self.step);
960 if (package.dependencies) |deps| {
961 for (deps) |dep| {
962 self.addRecursiveBuildDeps(dep);
963 }
964 }
963pub fn addOptions(cs: *CompileStep, module_name: []const u8, options: *OptionsStep) void {
964 addModule(cs, module_name, options.createModule());
965965}
966966
967pub fn addPackagePath(self: *CompileStep, name: []const u8, pkg_index_path: []const u8) void {
968 self.addPackage(Pkg{
969 .name = self.builder.dupe(name),
970 .source = .{ .path = self.builder.dupe(pkg_index_path) },
971 });
967fn addRecursiveBuildDeps(cs: *CompileStep, module: *Module) void {
968 module.source_file.addStepDependencies(&cs.step);
969 for (module.dependencies.values()) |dep| {
970 cs.addRecursiveBuildDeps(dep);
971 }
972972}
973973
974974/// If Vcpkg was found on the system, it will be added to include and lib
......@@ -1023,16 +1023,21 @@ fn linkLibraryOrObject(self: *CompileStep, other: *CompileStep) void {
10231023 self.include_dirs.append(.{ .other_step = other }) catch @panic("OOM");
10241024}
10251025
1026fn makePackageCmd(self: *CompileStep, pkg: Pkg, zig_args: *ArrayList([]const u8)) error{OutOfMemory}!void {
1027 const builder = self.builder;
1028
1026fn appendModuleArgs(
1027 cs: *CompileStep,
1028 zig_args: *ArrayList([]const u8),
1029 name: []const u8,
1030 module: *Module,
1031) error{OutOfMemory}!void {
10291032 try zig_args.append("--pkg-begin");
1030 try zig_args.append(pkg.name);
1031 try zig_args.append(builder.pathFromRoot(pkg.source.getPath(self.builder)));
1032
1033 if (pkg.dependencies) |dependencies| {
1034 for (dependencies) |sub_pkg| {
1035 try self.makePackageCmd(sub_pkg, zig_args);
1033 try zig_args.append(name);
1034 try zig_args.append(module.builder.pathFromRoot(module.source_file.getPath(module.builder)));
1035
1036 {
1037 const keys = module.dependencies.keys();
1038 for (module.dependencies.values()) |sub_module, i| {
1039 const sub_name = keys[i];
1040 try cs.appendModuleArgs(zig_args, sub_name, sub_module);
10361041 }
10371042 }
10381043
......@@ -1563,8 +1568,12 @@ fn make(step: *Step) !void {
15631568 try zig_args.append("--test-no-exec");
15641569 }
15651570
1566 for (self.packages.items) |pkg| {
1567 try self.makePackageCmd(pkg, &zig_args);
1571 {
1572 const keys = self.modules.keys();
1573 for (self.modules.values()) |module, i| {
1574 const name = keys[i];
1575 try self.appendModuleArgs(&zig_args, name, module);
1576 }
15681577 }
15691578
15701579 for (self.include_dirs.items) |include_dir| {
......@@ -1942,46 +1951,6 @@ fn getPkgConfigList(self: *std.Build) ![]const PkgConfigPkg {
19421951 }
19431952}
19441953
1945test "addPackage" {
1946 if (builtin.os.tag == .wasi) return error.SkipZigTest;
1947
1948 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
1949 defer arena.deinit();
1950
1951 const host = try NativeTargetInfo.detect(.{});
1952
1953 var builder = try std.Build.create(
1954 arena.allocator(),
1955 "test",
1956 "test",
1957 "test",
1958 "test",
1959 host,
1960 );
1961 defer builder.destroy();
1962
1963 const pkg_dep = Pkg{
1964 .name = "pkg_dep",
1965 .source = .{ .path = "/not/a/pkg_dep.zig" },
1966 };
1967 const pkg_top = Pkg{
1968 .name = "pkg_dep",
1969 .source = .{ .path = "/not/a/pkg_top.zig" },
1970 .dependencies = &[_]Pkg{pkg_dep},
1971 };
1972
1973 var exe = builder.addExecutable(.{
1974 .name = "not_an_executable",
1975 .root_source_file = .{ .path = "/not/an/executable.zig" },
1976 });
1977 exe.addPackage(pkg_top);
1978
1979 try std.testing.expectEqual(@as(usize, 1), exe.packages.items.len);
1980
1981 const dupe = exe.packages.items[0];
1982 try std.testing.expectEqualStrings(pkg_top.name, dupe.name);
1983}
1984
19851954fn addFlag(args: *ArrayList([]const u8), comptime name: []const u8, opt: ?bool) !void {
19861955 const cond = opt orelse return;
19871956 try args.ensureUnusedCapacity(1);
lib/std/Build/OptionsStep.zig+5-2
......@@ -204,8 +204,11 @@ pub fn addOptionArtifact(self: *OptionsStep, name: []const u8, artifact: *Compil
204204 self.step.dependOn(&artifact.step);
205205}
206206
207pub fn getPackage(self: *OptionsStep, package_name: []const u8) std.Build.Pkg {
208 return .{ .name = package_name, .source = self.getSource() };
207pub fn createModule(self: *OptionsStep) *std.Build.Module {
208 return self.builder.createModule(.{
209 .source_file = self.getSource(),
210 .dependencies = &.{},
211 });
209212}
210213
211214pub fn getSource(self: *OptionsStep) FileSource {
lib/std/array_list.zig+28-4
......@@ -482,14 +482,14 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
482482
483483 /// Return the last element from the list.
484484 /// Asserts the list has at least one item.
485 pub fn getLast(self: *Self) T {
485 pub fn getLast(self: Self) T {
486486 const val = self.items[self.items.len - 1];
487487 return val;
488488 }
489489
490490 /// Return the last element from the list, or
491491 /// return `null` if list is empty.
492 pub fn getLastOrNull(self: *Self) ?T {
492 pub fn getLastOrNull(self: Self) ?T {
493493 if (self.items.len == 0) return null;
494494 return self.getLast();
495495 }
......@@ -961,14 +961,14 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
961961
962962 /// Return the last element from the list.
963963 /// Asserts the list has at least one item.
964 pub fn getLast(self: *Self) T {
964 pub fn getLast(self: Self) T {
965965 const val = self.items[self.items.len - 1];
966966 return val;
967967 }
968968
969969 /// Return the last element from the list, or
970970 /// return `null` if list is empty.
971 pub fn getLastOrNull(self: *Self) ?T {
971 pub fn getLastOrNull(self: Self) ?T {
972972 if (self.items.len == 0) return null;
973973 return self.getLast();
974974 }
......@@ -1719,3 +1719,27 @@ test "std.ArrayList(?u32).popOrNull()" {
17191719 try testing.expect(list.popOrNull().? == null);
17201720 try testing.expect(list.popOrNull() == null);
17211721}
1722
1723test "std.ArrayList(u32).getLast()" {
1724 const a = testing.allocator;
1725
1726 var list = ArrayList(u32).init(a);
1727 defer list.deinit();
1728
1729 try list.append(2);
1730 const const_list = list;
1731 try testing.expectEqual(const_list.getLast(), 2);
1732}
1733
1734test "std.ArrayList(u32).getLastOrNull()" {
1735 const a = testing.allocator;
1736
1737 var list = ArrayList(u32).init(a);
1738 defer list.deinit();
1739
1740 try testing.expectEqual(list.getLastOrNull(), null);
1741
1742 try list.append(2);
1743 const const_list = list;
1744 try testing.expectEqual(const_list.getLastOrNull().?, 2);
1745}
lib/std/math/big.zig-1
......@@ -13,7 +13,6 @@ pub const Log2Limb = std.math.Log2Int(Limb);
1313
1414comptime {
1515 assert(std.math.floorPowerOfTwo(usize, limb_info.bits) == limb_info.bits);
16 assert(limb_info.bits <= 64); // u128 set is unsupported
1716 assert(limb_info.signedness == .unsigned);
1817}
1918
lib/std/math/big/int.zig+3-8
......@@ -30,7 +30,7 @@ pub fn calcLimbLen(scalar: anytype) usize {
3030 }
3131
3232 const w_value = std.math.absCast(scalar);
33 return @divFloor(@intCast(Limb, math.log2(w_value)), limb_bits) + 1;
33 return @intCast(usize, @divFloor(@intCast(Limb, math.log2(w_value)), limb_bits) + 1);
3434}
3535
3636pub fn calcToStringLimbsBufferLen(a_len: usize, base: u8) usize {
......@@ -238,10 +238,7 @@ pub const Mutable = struct {
238238 var i: usize = 0;
239239 while (true) : (i += 1) {
240240 self.limbs[i] = @truncate(Limb, w_value);
241
242 // TODO: shift == 64 at compile-time fails. Fails on u128 limbs.
243 w_value >>= limb_bits / 2;
244 w_value >>= limb_bits / 2;
241 w_value >>= limb_bits;
245242
246243 if (w_value == 0) break;
247244 }
......@@ -258,9 +255,7 @@ pub const Mutable = struct {
258255 comptime var i = 0;
259256 inline while (true) : (i += 1) {
260257 self.limbs[i] = w_value & mask;
261
262 w_value >>= limb_bits / 2;
263 w_value >>= limb_bits / 2;
258 w_value >>= limb_bits;
264259
265260 if (w_value == 0) break;
266261 }
lib/std/os/linux.zig+2
......@@ -40,6 +40,7 @@ const arch_bits = switch (native_arch) {
4040 .riscv64 => @import("linux/riscv64.zig"),
4141 .sparc64 => @import("linux/sparc64.zig"),
4242 .mips, .mipsel => @import("linux/mips.zig"),
43 .mips64, .mips64el => @import("linux/mips64.zig"),
4344 .powerpc => @import("linux/powerpc.zig"),
4445 .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"),
4546 else => struct {},
......@@ -101,6 +102,7 @@ pub const SYS = switch (@import("builtin").cpu.arch) {
101102 .riscv64 => syscalls.RiscV64,
102103 .sparc64 => syscalls.Sparc64,
103104 .mips, .mipsel => syscalls.Mips,
105 .mips64, .mips64el => syscalls.Mips64,
104106 .powerpc => syscalls.PowerPC,
105107 .powerpc64, .powerpc64le => syscalls.PowerPC64,
106108 else => @compileError("The Zig Standard Library is missing syscall definitions for the target CPU architecture"),
lib/std/os/linux/mips64.zig created+413
......@@ -0,0 +1,413 @@
1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3const linux = std.os.linux;
4const SYS = linux.SYS;
5const socklen_t = linux.socklen_t;
6const iovec = std.os.iovec;
7const iovec_const = std.os.iovec_const;
8const uid_t = linux.uid_t;
9const gid_t = linux.gid_t;
10const pid_t = linux.pid_t;
11const sockaddr = linux.sockaddr;
12const timespec = linux.timespec;
13
14pub fn syscall0(number: SYS) usize {
15 return asm volatile (
16 \\ syscall
17 \\ blez $7, 1f
18 \\ dsubu $2, $0, $2
19 \\ 1:
20 : [ret] "={$2}" (-> usize),
21 : [number] "{$2}" (@enumToInt(number)),
22 : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
23 );
24}
25
26pub fn syscall_pipe(fd: *[2]i32) usize {
27 return asm volatile (
28 \\ .set noat
29 \\ .set noreorder
30 \\ syscall
31 \\ blez $7, 1f
32 \\ nop
33 \\ b 2f
34 \\ subu $2, $0, $2
35 \\ 1:
36 \\ sw $2, 0($4)
37 \\ sw $3, 4($4)
38 \\ 2:
39 : [ret] "={$2}" (-> usize),
40 : [number] "{$2}" (@enumToInt(SYS.pipe)),
41 [fd] "{$4}" (fd),
42 : "$1", "$3", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
43 );
44}
45
46pub fn syscall1(number: SYS, arg1: usize) usize {
47 return asm volatile (
48 \\ syscall
49 \\ blez $7, 1f
50 \\ dsubu $2, $0, $2
51 \\ 1:
52 : [ret] "={$2}" (-> usize),
53 : [number] "{$2}" (@enumToInt(number)),
54 [arg1] "{$4}" (arg1),
55 : "$1", "$3", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
56 );
57}
58
59pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
60 return asm volatile (
61 \\ syscall
62 \\ blez $7, 1f
63 \\ dsubu $2, $0, $2
64 \\ 1:
65 : [ret] "={$2}" (-> usize),
66 : [number] "{$2}" (@enumToInt(number)),
67 [arg1] "{$4}" (arg1),
68 [arg2] "{$5}" (arg2),
69 : "$1", "$3", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
70 );
71}
72
73pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
74 return asm volatile (
75 \\ syscall
76 \\ blez $7, 1f
77 \\ dsubu $2, $0, $2
78 \\ 1:
79 : [ret] "={$2}" (-> usize),
80 : [number] "{$2}" (@enumToInt(number)),
81 [arg1] "{$4}" (arg1),
82 [arg2] "{$5}" (arg2),
83 [arg3] "{$6}" (arg3),
84 : "$1", "$3", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
85 );
86}
87
88pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
89 return asm volatile (
90 \\ syscall
91 \\ blez $7, 1f
92 \\ dsubu $2, $0, $2
93 \\ 1:
94 : [ret] "={$2}" (-> usize),
95 : [number] "{$2}" (@enumToInt(number)),
96 [arg1] "{$4}" (arg1),
97 [arg2] "{$5}" (arg2),
98 [arg3] "{$6}" (arg3),
99 [arg4] "{$7}" (arg4),
100 : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
101 );
102}
103
104pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
105 return asm volatile (
106 \\ syscall
107 \\ blez $7, 1f
108 \\ dsubu $2, $0, $2
109 \\ 1:
110 : [ret] "={$2}" (-> usize),
111 : [number] "{$2}" (@enumToInt(number)),
112 [arg1] "{$4}" (arg1),
113 [arg2] "{$5}" (arg2),
114 [arg3] "{$6}" (arg3),
115 [arg4] "{$7}" (arg4),
116 [arg5] "{$8}" (arg5),
117 : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
118 );
119}
120
121// NOTE: The o32 calling convention requires the callee to reserve 16 bytes for
122// the first four arguments even though they're passed in $a0-$a3.
123
124pub fn syscall6(
125 number: SYS,
126 arg1: usize,
127 arg2: usize,
128 arg3: usize,
129 arg4: usize,
130 arg5: usize,
131 arg6: usize,
132) usize {
133 return asm volatile (
134 \\ syscall
135 \\ blez $7, 1f
136 \\ dsubu $2, $0, $2
137 \\ 1:
138 : [ret] "={$2}" (-> usize),
139 : [number] "{$2}" (@enumToInt(number)),
140 [arg1] "{$4}" (arg1),
141 [arg2] "{$5}" (arg2),
142 [arg3] "{$6}" (arg3),
143 [arg4] "{$7}" (arg4),
144 [arg5] "{$8}" (arg5),
145 [arg6] "{$9}" (arg6),
146 : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
147 );
148}
149
150pub fn syscall7(
151 number: SYS,
152 arg1: usize,
153 arg2: usize,
154 arg3: usize,
155 arg4: usize,
156 arg5: usize,
157 arg6: usize,
158 arg7: usize,
159) usize {
160 return asm volatile (
161 \\ syscall
162 \\ blez $7, 1f
163 \\ dsubu $2, $0, $2
164 \\ 1:
165 : [ret] "={$2}" (-> usize),
166 : [number] "{$2}" (@enumToInt(number)),
167 [arg1] "{$4}" (arg1),
168 [arg2] "{$5}" (arg2),
169 [arg3] "{$6}" (arg3),
170 [arg4] "{$7}" (arg4),
171 [arg5] "{$8}" (arg5),
172 [arg6] "{$9}" (arg6),
173 [arg7] "{$10}" (arg7),
174 : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
175 );
176}
177
178const CloneFn = *const fn (arg: usize) callconv(.C) u8;
179
180/// This matches the libc clone function.
181pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
182
183pub fn restore() callconv(.Naked) void {
184 return asm volatile ("syscall"
185 :
186 : [number] "{$2}" (@enumToInt(SYS.rt_sigreturn)),
187 : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
188 );
189}
190
191pub fn restore_rt() callconv(.Naked) void {
192 return asm volatile ("syscall"
193 :
194 : [number] "{$2}" (@enumToInt(SYS.rt_sigreturn)),
195 : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
196 );
197}
198
199pub const O = struct {
200 pub const CREAT = 0o0400;
201 pub const EXCL = 0o02000;
202 pub const NOCTTY = 0o04000;
203 pub const TRUNC = 0o01000;
204 pub const APPEND = 0o0010;
205 pub const NONBLOCK = 0o0200;
206 pub const DSYNC = 0o0020;
207 pub const SYNC = 0o040020;
208 pub const RSYNC = 0o040020;
209 pub const DIRECTORY = 0o0200000;
210 pub const NOFOLLOW = 0o0400000;
211 pub const CLOEXEC = 0o02000000;
212
213 pub const ASYNC = 0o010000;
214 pub const DIRECT = 0o0100000;
215 pub const LARGEFILE = 0o020000;
216 pub const NOATIME = 0o01000000;
217 pub const PATH = 0o010000000;
218 pub const TMPFILE = 0o020200000;
219 pub const NDELAY = NONBLOCK;
220};
221
222pub const F = struct {
223 pub const DUPFD = 0;
224 pub const GETFD = 1;
225 pub const SETFD = 2;
226 pub const GETFL = 3;
227 pub const SETFL = 4;
228
229 pub const SETOWN = 24;
230 pub const GETOWN = 23;
231 pub const SETSIG = 10;
232 pub const GETSIG = 11;
233
234 pub const GETLK = 33;
235 pub const SETLK = 34;
236 pub const SETLKW = 35;
237
238 pub const RDLCK = 0;
239 pub const WRLCK = 1;
240 pub const UNLCK = 2;
241
242 pub const SETOWN_EX = 15;
243 pub const GETOWN_EX = 16;
244
245 pub const GETOWNER_UIDS = 17;
246};
247
248pub const LOCK = struct {
249 pub const SH = 1;
250 pub const EX = 2;
251 pub const UN = 8;
252 pub const NB = 4;
253};
254
255pub const MMAP2_UNIT = 4096;
256
257pub const MAP = struct {
258 pub const NORESERVE = 0x0400;
259 pub const GROWSDOWN = 0x1000;
260 pub const DENYWRITE = 0x2000;
261 pub const EXECUTABLE = 0x4000;
262 pub const LOCKED = 0x8000;
263 pub const @"32BIT" = 0x40;
264};
265
266pub const VDSO = struct {
267 pub const CGT_SYM = "__kernel_clock_gettime";
268 pub const CGT_VER = "LINUX_2.6.39";
269};
270
271pub const Flock = extern struct {
272 type: i16,
273 whence: i16,
274 __pad0: [4]u8,
275 start: off_t,
276 len: off_t,
277 pid: pid_t,
278 __unused: [4]u8,
279};
280
281pub const msghdr = extern struct {
282 name: ?*sockaddr,
283 namelen: socklen_t,
284 iov: [*]iovec,
285 iovlen: i32,
286 control: ?*anyopaque,
287 controllen: socklen_t,
288 flags: i32,
289};
290
291pub const msghdr_const = extern struct {
292 name: ?*const sockaddr,
293 namelen: socklen_t,
294 iov: [*]const iovec_const,
295 iovlen: i32,
296 control: ?*const anyopaque,
297 controllen: socklen_t,
298 flags: i32,
299};
300
301pub const blksize_t = i32;
302pub const nlink_t = u32;
303pub const time_t = i32;
304pub const mode_t = u32;
305pub const off_t = i64;
306pub const ino_t = u64;
307pub const dev_t = u64;
308pub const blkcnt_t = i64;
309
310// The `stat` definition used by the Linux kernel.
311pub const Stat = extern struct {
312 dev: u32,
313 __pad0: [3]u32, // Reserved for st_dev expansion
314 ino: ino_t,
315 mode: mode_t,
316 nlink: nlink_t,
317 uid: uid_t,
318 gid: gid_t,
319 rdev: u32,
320 __pad1: [3]u32,
321 size: off_t,
322 atim: timespec,
323 mtim: timespec,
324 ctim: timespec,
325 blksize: blksize_t,
326 __pad3: u32,
327 blocks: blkcnt_t,
328 __pad4: [14]usize,
329
330 pub fn atime(self: @This()) timespec {
331 return self.atim;
332 }
333
334 pub fn mtime(self: @This()) timespec {
335 return self.mtim;
336 }
337
338 pub fn ctime(self: @This()) timespec {
339 return self.ctim;
340 }
341};
342
343pub const timeval = extern struct {
344 tv_sec: isize,
345 tv_usec: isize,
346};
347
348pub const timezone = extern struct {
349 tz_minuteswest: i32,
350 tz_dsttime: i32,
351};
352
353pub const Elf_Symndx = u32;
354
355pub const rlimit_resource = enum(c_int) {
356 /// Per-process CPU limit, in seconds.
357 CPU,
358
359 /// Largest file that can be created, in bytes.
360 FSIZE,
361
362 /// Maximum size of data segment, in bytes.
363 DATA,
364
365 /// Maximum size of stack segment, in bytes.
366 STACK,
367
368 /// Largest core file that can be created, in bytes.
369 CORE,
370
371 /// Number of open files.
372 NOFILE,
373
374 /// Address space limit.
375 AS,
376
377 /// Largest resident set size, in bytes.
378 /// This affects swapping; processes that are exceeding their
379 /// resident set size will be more likely to have physical memory
380 /// taken from them.
381 RSS,
382
383 /// Number of processes.
384 NPROC,
385
386 /// Locked-in-memory address space.
387 MEMLOCK,
388
389 /// Maximum number of file locks.
390 LOCKS,
391
392 /// Maximum number of pending signals.
393 SIGPENDING,
394
395 /// Maximum bytes in POSIX message queues.
396 MSGQUEUE,
397
398 /// Maximum nice priority allowed to raise to.
399 /// Nice levels 19 .. -20 correspond to 0 .. 39
400 /// values of this resource limit.
401 NICE,
402
403 /// Maximum realtime priority allowed for non-priviledged
404 /// processes.
405 RTPRIO,
406
407 /// Maximum CPU time in µs that a process scheduled under a real-time
408 /// scheduling policy may consume without making a blocking system
409 /// call before being forcibly descheduled.
410 RTTIME,
411
412 _,
413};
lib/std/os/linux/syscalls.zig+355
......@@ -2032,6 +2032,361 @@ pub const Mips = enum(usize) {
20322032 set_mempolicy_home_node = Linux + 450,
20332033};
20342034
2035pub const Mips64 = enum(usize) {
2036 pub const Linux = 5000;
2037
2038 read = Linux + 0,
2039 write = Linux + 1,
2040 open = Linux + 2,
2041 close = Linux + 3,
2042 stat = Linux + 4,
2043 fstat = Linux + 5,
2044 lstat = Linux + 6,
2045 poll = Linux + 7,
2046 lseek = Linux + 8,
2047 mmap = Linux + 9,
2048 mprotect = Linux + 10,
2049 munmap = Linux + 11,
2050 brk = Linux + 12,
2051 rt_sigaction = Linux + 13,
2052 rt_sigprocmask = Linux + 14,
2053 ioctl = Linux + 15,
2054 pread64 = Linux + 16,
2055 pwrite64 = Linux + 17,
2056 readv = Linux + 18,
2057 writev = Linux + 19,
2058 access = Linux + 20,
2059 pipe = Linux + 21,
2060 select = Linux + 22,
2061 sched_yield = Linux + 23,
2062 mremap = Linux + 24,
2063 msync = Linux + 25,
2064 mincore = Linux + 26,
2065 madvise = Linux + 27,
2066 shmget = Linux + 28,
2067 shmat = Linux + 29,
2068 shmctl = Linux + 30,
2069 dup = Linux + 31,
2070 dup2 = Linux + 32,
2071 pause = Linux + 33,
2072 nanosleep = Linux + 34,
2073 getitimer = Linux + 35,
2074 alarm = Linux + 36,
2075 setitimer = Linux + 37,
2076 getpid = Linux + 38,
2077 sendfile = Linux + 39,
2078 socket = Linux + 40,
2079 connect = Linux + 41,
2080 accept = Linux + 42,
2081 sendto = Linux + 43,
2082 recvfrom = Linux + 44,
2083 sendmsg = Linux + 45,
2084 recvmsg = Linux + 46,
2085 shutdown = Linux + 47,
2086 bind = Linux + 48,
2087 listen = Linux + 49,
2088 getsockname = Linux + 50,
2089 getpeername = Linux + 51,
2090 socketpair = Linux + 52,
2091 setsockopt = Linux + 53,
2092 getsockopt = Linux + 54,
2093 clone = Linux + 55,
2094 fork = Linux + 56,
2095 execve = Linux + 57,
2096 exit = Linux + 58,
2097 wait4 = Linux + 59,
2098 kill = Linux + 60,
2099 uname = Linux + 61,
2100 semget = Linux + 62,
2101 semop = Linux + 63,
2102 semctl = Linux + 64,
2103 shmdt = Linux + 65,
2104 msgget = Linux + 66,
2105 msgsnd = Linux + 67,
2106 msgrcv = Linux + 68,
2107 msgctl = Linux + 69,
2108 fcntl = Linux + 70,
2109 flock = Linux + 71,
2110 fsync = Linux + 72,
2111 fdatasync = Linux + 73,
2112 truncate = Linux + 74,
2113 ftruncate = Linux + 75,
2114 getdents = Linux + 76,
2115 getcwd = Linux + 77,
2116 chdir = Linux + 78,
2117 fchdir = Linux + 79,
2118 rename = Linux + 80,
2119 mkdir = Linux + 81,
2120 rmdir = Linux + 82,
2121 creat = Linux + 83,
2122 link = Linux + 84,
2123 unlink = Linux + 85,
2124 symlink = Linux + 86,
2125 readlink = Linux + 87,
2126 chmod = Linux + 88,
2127 fchmod = Linux + 89,
2128 chown = Linux + 90,
2129 fchown = Linux + 91,
2130 lchown = Linux + 92,
2131 umask = Linux + 93,
2132 gettimeofday = Linux + 94,
2133 getrlimit = Linux + 95,
2134 getrusage = Linux + 96,
2135 sysinfo = Linux + 97,
2136 times = Linux + 98,
2137 ptrace = Linux + 99,
2138 getuid = Linux + 100,
2139 syslog = Linux + 101,
2140 getgid = Linux + 102,
2141 setuid = Linux + 103,
2142 setgid = Linux + 104,
2143 geteuid = Linux + 105,
2144 getegid = Linux + 106,
2145 setpgid = Linux + 107,
2146 getppid = Linux + 108,
2147 getpgrp = Linux + 109,
2148 setsid = Linux + 110,
2149 setreuid = Linux + 111,
2150 setregid = Linux + 112,
2151 getgroups = Linux + 113,
2152 setgroups = Linux + 114,
2153 setresuid = Linux + 115,
2154 getresuid = Linux + 116,
2155 setresgid = Linux + 117,
2156 getresgid = Linux + 118,
2157 getpgid = Linux + 119,
2158 setfsuid = Linux + 120,
2159 setfsgid = Linux + 121,
2160 getsid = Linux + 122,
2161 capget = Linux + 123,
2162 capset = Linux + 124,
2163 rt_sigpending = Linux + 125,
2164 rt_sigtimedwait = Linux + 126,
2165 rt_sigqueueinfo = Linux + 127,
2166 rt_sigsuspend = Linux + 128,
2167 sigaltstack = Linux + 129,
2168 utime = Linux + 130,
2169 mknod = Linux + 131,
2170 personality = Linux + 132,
2171 ustat = Linux + 133,
2172 statfs = Linux + 134,
2173 fstatfs = Linux + 135,
2174 sysfs = Linux + 136,
2175 getpriority = Linux + 137,
2176 setpriority = Linux + 138,
2177 sched_setparam = Linux + 139,
2178 sched_getparam = Linux + 140,
2179 sched_setscheduler = Linux + 141,
2180 sched_getscheduler = Linux + 142,
2181 sched_get_priority_max = Linux + 143,
2182 sched_get_priority_min = Linux + 144,
2183 sched_rr_get_interval = Linux + 145,
2184 mlock = Linux + 146,
2185 munlock = Linux + 147,
2186 mlockall = Linux + 148,
2187 munlockall = Linux + 149,
2188 vhangup = Linux + 150,
2189 pivot_root = Linux + 151,
2190 _sysctl = Linux + 152,
2191 prctl = Linux + 153,
2192 adjtimex = Linux + 154,
2193 setrlimit = Linux + 155,
2194 chroot = Linux + 156,
2195 sync = Linux + 157,
2196 acct = Linux + 158,
2197 settimeofday = Linux + 159,
2198 mount = Linux + 160,
2199 umount2 = Linux + 161,
2200 swapon = Linux + 162,
2201 swapoff = Linux + 163,
2202 reboot = Linux + 164,
2203 sethostname = Linux + 165,
2204 setdomainname = Linux + 166,
2205 create_module = Linux + 167,
2206 init_module = Linux + 168,
2207 delete_module = Linux + 169,
2208 get_kernel_syms = Linux + 170,
2209 query_module = Linux + 171,
2210 quotactl = Linux + 172,
2211 nfsservctl = Linux + 173,
2212 getpmsg = Linux + 174,
2213 putpmsg = Linux + 175,
2214 afs_syscall = Linux + 176,
2215 reserved177 = Linux + 177,
2216 gettid = Linux + 178,
2217 readahead = Linux + 179,
2218 setxattr = Linux + 180,
2219 lsetxattr = Linux + 181,
2220 fsetxattr = Linux + 182,
2221 getxattr = Linux + 183,
2222 lgetxattr = Linux + 184,
2223 fgetxattr = Linux + 185,
2224 listxattr = Linux + 186,
2225 llistxattr = Linux + 187,
2226 flistxattr = Linux + 188,
2227 removexattr = Linux + 189,
2228 lremovexattr = Linux + 190,
2229 fremovexattr = Linux + 191,
2230 tkill = Linux + 192,
2231 reserved193 = Linux + 193,
2232 futex = Linux + 194,
2233 sched_setaffinity = Linux + 195,
2234 sched_getaffinity = Linux + 196,
2235 cacheflush = Linux + 197,
2236 cachectl = Linux + 198,
2237 sysmips = Linux + 199,
2238 io_setup = Linux + 200,
2239 io_destroy = Linux + 201,
2240 io_getevents = Linux + 202,
2241 io_submit = Linux + 203,
2242 io_cancel = Linux + 204,
2243 exit_group = Linux + 205,
2244 lookup_dcookie = Linux + 206,
2245 epoll_create = Linux + 207,
2246 epoll_ctl = Linux + 208,
2247 epoll_wait = Linux + 209,
2248 remap_file_pages = Linux + 210,
2249 rt_sigreturn = Linux + 211,
2250 set_tid_address = Linux + 212,
2251 restart_syscall = Linux + 213,
2252 semtimedop = Linux + 214,
2253 fadvise64 = Linux + 215,
2254 timer_create = Linux + 216,
2255 timer_settime = Linux + 217,
2256 timer_gettime = Linux + 218,
2257 timer_getoverrun = Linux + 219,
2258 timer_delete = Linux + 220,
2259 clock_settime = Linux + 221,
2260 clock_gettime = Linux + 222,
2261 clock_getres = Linux + 223,
2262 clock_nanosleep = Linux + 224,
2263 tgkill = Linux + 225,
2264 utimes = Linux + 226,
2265 mbind = Linux + 227,
2266 get_mempolicy = Linux + 228,
2267 set_mempolicy = Linux + 229,
2268 mq_open = Linux + 230,
2269 mq_unlink = Linux + 231,
2270 mq_timedsend = Linux + 232,
2271 mq_timedreceive = Linux + 233,
2272 mq_notify = Linux + 234,
2273 mq_getsetattr = Linux + 235,
2274 vserver = Linux + 236,
2275 waitid = Linux + 237,
2276 add_key = Linux + 239,
2277 request_key = Linux + 240,
2278 keyctl = Linux + 241,
2279 set_thread_area = Linux + 242,
2280 inotify_init = Linux + 243,
2281 inotify_add_watch = Linux + 244,
2282 inotify_rm_watch = Linux + 245,
2283 migrate_pages = Linux + 246,
2284 openat = Linux + 247,
2285 mkdirat = Linux + 248,
2286 mknodat = Linux + 249,
2287 fchownat = Linux + 250,
2288 futimesat = Linux + 251,
2289 newfstatat = Linux + 252,
2290 unlinkat = Linux + 253,
2291 renameat = Linux + 254,
2292 linkat = Linux + 255,
2293 symlinkat = Linux + 256,
2294 readlinkat = Linux + 257,
2295 fchmodat = Linux + 258,
2296 faccessat = Linux + 259,
2297 pselect6 = Linux + 260,
2298 ppoll = Linux + 261,
2299 unshare = Linux + 262,
2300 splice = Linux + 263,
2301 sync_file_range = Linux + 264,
2302 tee = Linux + 265,
2303 vmsplice = Linux + 266,
2304 move_pages = Linux + 267,
2305 set_robust_list = Linux + 268,
2306 get_robust_list = Linux + 269,
2307 kexec_load = Linux + 270,
2308 getcpu = Linux + 271,
2309 epoll_pwait = Linux + 272,
2310 ioprio_set = Linux + 273,
2311 ioprio_get = Linux + 274,
2312 utimensat = Linux + 275,
2313 signalfd = Linux + 276,
2314 timerfd = Linux + 277,
2315 eventfd = Linux + 278,
2316 fallocate = Linux + 279,
2317 timerfd_create = Linux + 280,
2318 timerfd_settime = Linux + 281,
2319 timerfd_gettime = Linux + 282,
2320 signalfd4 = Linux + 283,
2321 eventfd2 = Linux + 284,
2322 epoll_create1 = Linux + 285,
2323 dup3 = Linux + 286,
2324 pipe2 = Linux + 287,
2325 inotify_init1 = Linux + 288,
2326 preadv = Linux + 289,
2327 pwritev = Linux + 290,
2328 rt_tgsigqueueinfo = Linux + 291,
2329 perf_event_open = Linux + 292,
2330 accept4 = Linux + 293,
2331 recvmmsg = Linux + 294,
2332 fanotify_init = Linux + 295,
2333 fanotify_mark = Linux + 296,
2334 prlimit64 = Linux + 297,
2335 name_to_handle_at = Linux + 298,
2336 open_by_handle_at = Linux + 299,
2337 clock_adjtime = Linux + 300,
2338 syncfs = Linux + 301,
2339 sendmmsg = Linux + 302,
2340 setns = Linux + 303,
2341 process_vm_readv = Linux + 304,
2342 process_vm_writev = Linux + 305,
2343 kcmp = Linux + 306,
2344 finit_module = Linux + 307,
2345 getdents64 = Linux + 308,
2346 sched_setattr = Linux + 309,
2347 sched_getattr = Linux + 310,
2348 renameat2 = Linux + 311,
2349 seccomp = Linux + 312,
2350 getrandom = Linux + 313,
2351 memfd_create = Linux + 314,
2352 bpf = Linux + 315,
2353 execveat = Linux + 316,
2354 userfaultfd = Linux + 317,
2355 membarrier = Linux + 318,
2356 mlock2 = Linux + 319,
2357 copy_file_range = Linux + 320,
2358 preadv2 = Linux + 321,
2359 pwritev2 = Linux + 322,
2360 pkey_mprotect = Linux + 323,
2361 pkey_alloc = Linux + 324,
2362 pkey_free = Linux + 325,
2363 statx = Linux + 326,
2364 rseq = Linux + 327,
2365 io_pgetevents = Linux + 328,
2366 pidfd_send_signal = Linux + 424,
2367 io_uring_setup = Linux + 425,
2368 io_uring_enter = Linux + 426,
2369 io_uring_register = Linux + 427,
2370 open_tree = Linux + 428,
2371 move_mount = Linux + 429,
2372 fsopen = Linux + 430,
2373 fsconfig = Linux + 431,
2374 fsmount = Linux + 432,
2375 fspick = Linux + 433,
2376 pidfd_open = Linux + 434,
2377 clone3 = Linux + 435,
2378 close_range = Linux + 436,
2379 openat2 = Linux + 437,
2380 pidfd_getfd = Linux + 438,
2381 faccessat2 = Linux + 439,
2382 process_madvise = Linux + 440,
2383 epoll_pwait2 = Linux + 441,
2384 mount_setattr = Linux + 442,
2385 landlock_create_ruleset = Linux + 444,
2386 landlock_add_rule = Linux + 445,
2387 landlock_restrict_self = Linux + 446,
2388};
2389
20352390pub const PowerPC = enum(usize) {
20362391 restart_syscall = 0,
20372392 exit = 1,
lib/std/os/linux/tls.zig+5-5
......@@ -48,7 +48,7 @@ const TLSVariant = enum {
4848};
4949
5050const tls_variant = switch (native_arch) {
51 .arm, .armeb, .thumb, .aarch64, .aarch64_be, .riscv32, .riscv64, .mips, .mipsel, .powerpc, .powerpc64, .powerpc64le => TLSVariant.VariantI,
51 .arm, .armeb, .thumb, .aarch64, .aarch64_be, .riscv32, .riscv64, .mips, .mipsel, .mips64, .mips64el, .powerpc, .powerpc64, .powerpc64le => TLSVariant.VariantI,
5252 .x86_64, .x86, .sparc64 => TLSVariant.VariantII,
5353 else => @compileError("undefined tls_variant for this architecture"),
5454};
......@@ -64,7 +64,7 @@ const tls_tcb_size = switch (native_arch) {
6464
6565// Controls if the TP points to the end of the TCB instead of its beginning
6666const tls_tp_points_past_tcb = switch (native_arch) {
67 .riscv32, .riscv64, .mips, .mipsel, .powerpc, .powerpc64, .powerpc64le => true,
67 .riscv32, .riscv64, .mips, .mipsel, .mips64, .mips64el, .powerpc, .powerpc64, .powerpc64le => true,
6868 else => false,
6969};
7070
......@@ -72,12 +72,12 @@ const tls_tp_points_past_tcb = switch (native_arch) {
7272// make the generated code more efficient
7373
7474const tls_tp_offset = switch (native_arch) {
75 .mips, .mipsel, .powerpc, .powerpc64, .powerpc64le => 0x7000,
75 .mips, .mipsel, .mips64, .mips64el, .powerpc, .powerpc64, .powerpc64le => 0x7000,
7676 else => 0,
7777};
7878
7979const tls_dtv_offset = switch (native_arch) {
80 .mips, .mipsel, .powerpc, .powerpc64, .powerpc64le => 0x8000,
80 .mips, .mipsel, .mips64, .mips64el, .powerpc, .powerpc64, .powerpc64le => 0x8000,
8181 .riscv32, .riscv64 => 0x800,
8282 else => 0,
8383};
......@@ -156,7 +156,7 @@ pub fn setThreadPointer(addr: usize) void {
156156 : [addr] "r" (addr),
157157 );
158158 },
159 .mips, .mipsel => {
159 .mips, .mipsel, .mips64, .mips64el => {
160160 const rc = std.os.linux.syscall1(.set_thread_area, addr);
161161 assert(rc == 0);
162162 },
lib/std/start.zig+1-1
......@@ -327,7 +327,7 @@ fn _start() callconv(.Naked) noreturn {
327327 : [argc] "={sp}" (-> [*]usize),
328328 );
329329 },
330 .mips, .mipsel => {
330 .mips, .mipsel, .mips64, .mips64el => {
331331 // The lr is already zeroed on entry, as specified by the ABI.
332332 argc_argv_ptr = asm volatile (
333333 \\ move $fp, $0
src/Module.zig-12
......@@ -531,9 +531,6 @@ pub const Decl = struct {
531531 /// What kind of a declaration is this.
532532 kind: Kind,
533533
534 /// TODO remove this once Wasm backend catches up
535 fn_link: ?link.File.Wasm.FnData = null,
536
537534 /// The shallow set of other decls whose typed_value could possibly change if this Decl's
538535 /// typed_value is modified.
539536 dependants: DepsTable = .{},
......@@ -5247,11 +5244,6 @@ pub fn clearDecl(
52475244 if (decl.has_tv) {
52485245 if (decl.ty.isFnOrHasRuntimeBits()) {
52495246 mod.comp.bin_file.freeDecl(decl_index);
5250
5251 decl.fn_link = switch (mod.comp.bin_file.tag) {
5252 .wasm => link.File.Wasm.FnData.empty,
5253 else => null,
5254 };
52555247 }
52565248 if (decl.getInnerNamespace()) |namespace| {
52575249 try namespace.deleteAllDecls(mod, outdated_decls);
......@@ -5652,10 +5644,6 @@ pub fn allocateNewDecl(
56525644 .deletion_flag = false,
56535645 .zir_decl_index = 0,
56545646 .src_scope = src_scope,
5655 .fn_link = switch (mod.comp.bin_file.tag) {
5656 .wasm => link.File.Wasm.FnData.empty,
5657 else => null,
5658 },
56595647 .generation = 0,
56605648 .is_pub = false,
56615649 .is_exported = false,
src/arch/wasm/CodeGen.zig+3-3
......@@ -1194,7 +1194,7 @@ fn genFunc(func: *CodeGen) InnerError!void {
11941194 const fn_info = func.decl.ty.fnInfo();
11951195 var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types, fn_info.return_type, func.target);
11961196 defer func_type.deinit(func.gpa);
1197 func.decl.fn_link.?.type_index = try func.bin_file.putOrGetFuncType(func_type);
1197 _ = try func.bin_file.storeDeclType(func.decl_index, func_type);
11981198
11991199 var cc_result = try func.resolveCallingConventionValues(func.decl.ty);
12001200 defer cc_result.deinit(func.gpa);
......@@ -2131,12 +2131,12 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
21312131 defer func_type.deinit(func.gpa);
21322132 const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_fn.data.owner_decl);
21332133 const atom = func.bin_file.getAtomPtr(atom_index);
2134 ext_decl.fn_link.?.type_index = try func.bin_file.putOrGetFuncType(func_type);
2134 const type_index = try func.bin_file.storeDeclType(extern_fn.data.owner_decl, func_type);
21352135 try func.bin_file.addOrUpdateImport(
21362136 mem.sliceTo(ext_decl.name, 0),
21372137 atom.getSymbolIndex().?,
21382138 ext_decl.getExternFn().?.lib_name,
2139 ext_decl.fn_link.?.type_index,
2139 type_index,
21402140 );
21412141 break :blk extern_fn.data.owner_decl;
21422142 } else if (func_val.castTag(.decl_ref)) |decl_ref| {
src/link/Wasm.zig+19-13
......@@ -46,6 +46,9 @@ host_name: []const u8 = "env",
4646/// List of all `Decl` that are currently alive.
4747/// Each index maps to the corresponding `Atom.Index`.
4848decls: std.AutoHashMapUnmanaged(Module.Decl.Index, Atom.Index) = .{},
49/// Mapping between an `Atom` and its type index representing the Wasm
50/// type of the function signature.
51atom_types: std.AutoHashMapUnmanaged(Atom.Index, u32) = .{},
4952/// List of all symbols generated by Zig code.
5053symbols: std.ArrayListUnmanaged(Symbol) = .{},
5154/// List of symbol indexes which are free to be used.
......@@ -175,15 +178,6 @@ pub const Segment = struct {
175178 offset: u32,
176179};
177180
178pub const FnData = struct {
179 /// Reference to the wasm type that represents this function.
180 type_index: u32,
181
182 pub const empty: FnData = .{
183 .type_index = undefined,
184 };
185};
186
187181pub const Export = struct {
188182 sym_index: ?u32 = null,
189183};
......@@ -961,6 +955,7 @@ pub fn deinit(wasm: *Wasm) void {
961955 }
962956
963957 wasm.decls.deinit(gpa);
958 wasm.atom_types.deinit(gpa);
964959 wasm.symbols.deinit(gpa);
965960 wasm.symbols_free_list.deinit(gpa);
966961 wasm.globals.deinit(gpa);
......@@ -1607,7 +1602,7 @@ const Kind = union(enum) {
16071602 initialized,
16081603 synthetic,
16091604 },
1610 function: FnData,
1605 function: void,
16111606
16121607 /// Returns the segment name the data kind represents.
16131608 /// Asserts `kind` has its active tag set to `data`.
......@@ -1626,12 +1621,13 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void {
16261621 const atom = wasm.getAtomPtr(atom_index);
16271622 const symbol = (SymbolLoc{ .file = null, .index = atom.sym_index }).getSymbol(wasm);
16281623 const final_index: u32 = switch (kind) {
1629 .function => |fn_data| result: {
1624 .function => result: {
16301625 const index = @intCast(u32, wasm.functions.count() + wasm.imported_functions_count);
1626 const type_index = wasm.atom_types.get(atom_index).?;
16311627 try wasm.functions.putNoClobber(
16321628 wasm.base.allocator,
16331629 .{ .file = null, .index = index },
1634 .{ .type_index = fn_data.type_index },
1630 .{ .type_index = type_index },
16351631 );
16361632 symbol.tag = .function;
16371633 symbol.index = index;
......@@ -2829,7 +2825,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
28292825 if (decl.isExtern()) continue;
28302826 const atom_index = entry.value_ptr.*;
28312827 if (decl.ty.zigTypeTag() == .Fn) {
2832 try wasm.parseAtom(atom_index, .{ .function = decl.fn_link.? });
2828 try wasm.parseAtom(atom_index, .function);
28332829 } else if (decl.getVariable()) |variable| {
28342830 if (!variable.is_mutable) {
28352831 try wasm.parseAtom(atom_index, .{ .data = .read_only });
......@@ -4172,3 +4168,13 @@ pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 {
41724168 });
41734169 return index;
41744170}
4171
4172/// For the given `decl_index`, stores the corresponding type representing the function signature.
4173/// Asserts declaration has an associated `Atom`.
4174/// Returns the index into the list of types.
4175pub fn storeDeclType(wasm: *Wasm, decl_index: Module.Decl.Index, func_type: std.wasm.Type) !u32 {
4176 const atom_index = wasm.decls.get(decl_index).?;
4177 const index = try wasm.putOrGetFuncType(func_type);
4178 try wasm.atom_types.put(wasm.base.allocator, atom_index, index);
4179 return index;
4180}
test/standalone/pkg_import/build.zig+1-1
......@@ -8,7 +8,7 @@ pub fn build(b: *std.Build) void {
88 .root_source_file = .{ .path = "test.zig" },
99 .optimize = optimize,
1010 });
11 exe.addPackagePath("my_pkg", "pkg.zig");
11 exe.addAnonymousModule("my_pkg", .{ .source_file = .{ .path = "pkg.zig" } });
1212
1313 const run = exe.run();
1414